コード例 #1
0
		internal void ExecuteWhere(string From_TableName, object[,] Where_NameCondValue, out Set ROWIDS)
		{
			
		
				string TableName=From_TableName;
				if(Where_NameCondValue==null) Where_NameCondValue=new object[0,0];
				Field[] flds = GetFields(TableName);

			// Assertion
			if(true)
			{
				Index DELNDX = GetIndex(From_TableName,flds[0]);
				int __rows1 = DELNDX.GetRowCountForKey(false); // non-deleted rows count
				for(int k=1;k<flds.Length;k++)
				{
					if(flds[k].bIndexed)
					{
						Index _NDX = GetIndex(From_TableName,flds[k]);
						if(_NDX.ReverseCount()!=__rows1)
							throw new Exception("Corruption error.");
					}
				}
			}

				// map of fields in table
				Hashtable FieldMap = new Hashtable();
				foreach(Field f in flds)
				{
					FieldMap[f.Name]=f;
				}

				// Values in names with same type as field
				ArrayList Where = new ArrayList();
				Hashtable UsedFieldMap = new Hashtable();
				for(int n=0;n<Where_NameCondValue.GetLength(0);n++)
				{
					string fieldname = Where_NameCondValue[n,0].ToString();
					string op =	Where_NameCondValue[n,1].ToString();
					object val = Where_NameCondValue[n,2];


					bool oprec = (op=="=")||(op==">")||(op=="<")||(op=="!=")||(op==">=")||(op=="<=");
					if(!oprec)
						throw new Exception("Operand '"+op+"' unrecognized");

					if(!FieldMap.ContainsKey(fieldname)) throw new Exception("Column "+fieldname+" unrecognized");
					Field f = FieldMap[fieldname] as Field;
					UsedFieldMap[f]=f;

					int priority=0;
					if(f.bIndexed&&f.bUnique&&(op=="=")) 
						priority=-4;
					else if(f.bIndexed&&(op=="="))
						priority=-3;
					else if(f.bIndexed&&f.bUnique&&((op=="<")||(op==">")||(op==">=")||(op=="<=")))
						priority=-2;
					else if(f.bIndexed&&((op=="<")||(op==">")||(op==">=")||(op=="<=")))
						priority=-1;
					
					object v=Variant.Object2Variant(val,f.type).obj;

					Where.Add(new object[]{f,op,v,priority});
				}

				// Sorting of fields to make search faster
				if(true)
				{
					// Order:
					// Indexed-unique with = condition -4
					// Indexed with = condition -3
					// Indexed-unique with < or > condition -2
					// Indexed with < or > condition -1
					// The rest 0
					Where.Sort(new WhereComp());
				}

				// Let's do the search
				if(Where.Count>0)
				{
					ROWIDS = null;
					for(int n=0;(n<Where.Count);n++)
					{
						Field f = (Where[n] as object[])[0] as Field;
						string op = (Where[n] as object[])[1] as string;
						object val = (Where[n] as object[])[2] as object;

						if(f.bIndexed)
						{
							if(f.bUnique)
							{
								if(op=="=")
								{
									Index ndx = this.GetIndex(TableName,f);
									if(ndx.ExistsKey(val))
									{
										long row = ndx.PeekOne(val);
										if(ROWIDS==null)
										{
											ROWIDS = new SortedSet();
											ROWIDS.Add( row );
											continue;
										}
										else if(ROWIDS.Contains( row ))
										{
											ROWIDS = new SortedSet();
											ROWIDS.Add( row );
											continue;
										}
										else
										{
											ROWIDS = new SortedSet();
											break;
										}
									}
									else
									{
										ROWIDS = new SortedSet();
										break;
									}
								}
//// beta begin
//								if(op=="!=")
//								{
//									Index ndx = this.GetIndex(TableName,f);
//									if(ndx.ExistsUnique(val))
//									{// the value exists in the index
//										// If the rowids collection do not exist already
//										if(ROWIDS==null)
//										{
//											// Fill a rowid collection without the removed rowid
//											rowids = new ArrayList( ndx.ht.Values );
//											rowids.Remove(ndx.ht[val]);
//											continue;
//										}
//										// If the rowids collection already exists
//										else
//										{
//											// If contains the value to exclude
//											if(rowids.Contains(val))
//											{
//												rowids.Remove(ndx.ht[val]);
//												if(rowids.Count==0) break; 
//												continue;
//											}
//											// If do not contains the value to exclude
//											else
//											{
//												continue;
//											}
//										}
//									}
//									else
//									{// the value do not exist in the index
//										continue;
//									}
//								}
////end beta
							}
							else
							{// clave no única
								if(ROWIDS==null)
								{
									Index ndx = this.GetIndex(TableName,flds[0]);
									ROWIDS = new SortedSet( ndx.GetRowSet(false) );
								}
								// begin op =
								if(op=="=")
								{
									Index ndx = this.GetIndex(TableName,f);
									Set hs = ndx.GetRowSet(val);
									if(hs.Count<ROWIDS.Count)
									{// hs is smaller than ROWIDS
										Set newSet = new SortedSet();
										foreach(long row in hs)
										{
											if(ROWIDS.Contains(row))
												newSet.Add(row);
										}
										ROWIDS=newSet;
									}
									else
									{// ROWIDS is smaller than hs
										Set newSet = new SortedSet();
										foreach(long row in ROWIDS)
										{
											if(hs.Contains(row))
												newSet.Add(row);
										}
										ROWIDS=newSet;
									}
									//ROWIDS = ROWIDS.Intersect( hs);
									if(ROWIDS.Count==0) break;
									else continue;
								}
								// end of op =
								// begin op !=
								if(op=="!=")
								{
									Index ndx = this.GetIndex(TableName,f);
									Set hs = ndx.GetRowSet(val);
									ROWIDS = ROWIDS.Minus( hs);
									if(ROWIDS.Count==0) break;
									else continue;
								}
								// end of op !=
								// begin op >
								if((op=="<")||(op==">")||(op=="<=")||(op==">=")) 
								{
									Index ndx = this.GetIndex(TableName,f);

									// Metemos en un set todos los ids de fila que llevamos hasta ahora
									// para luego irlas poniendo en una lista de seleccionadas
									Set nSet = new SortedSet();
									IComparable v = (IComparable)val;
									foreach(object key in ndx.Keys)
									{
										IComparable o = (IComparable)key;
										bool bAdd=false;
										if((op==">")&&(o.CompareTo(v)>0)) bAdd=true;
										else if((op=="<")&&(o.CompareTo(v)<0)) bAdd=true;
										else if((op==">=")&&(o.CompareTo(v)>=0)) bAdd=true;
										else if((op=="<=")&&(o.CompareTo(v)<=0)) bAdd=true;
										if(bAdd) 
											nSet = nSet.Union( ndx.GetRowSet(key) );
									}
									ROWIDS = ROWIDS.Intersect( nSet );
									if(ROWIDS.Count==0) break; 
									continue;
								}
								else
								{
									throw new Exception("Unsupported operator");
								}
								// end of op >
							}
						}
						// Linear search
						if(ROWIDS==null)
						{
							Index ndx = this.GetIndex(TableName,flds[0]);
							ROWIDS = new SortedSet( ndx.GetRowSet(false) ); 
						}
						if(true)
						{
							int tid = (int)TableName2TID[TableName];
							TableNameDef tnd = TID2Def[tid] as TableNameDef;
							int valSize = (int)f.DataSize();
							int Capacity = (PageSize-ContentPageDataOffset)/valSize;
							ArrayList pages = f.DataFID;
							if((pages.Count*Capacity)<tnd.rownum)
								throw new Exception("Row num corrupted.");
							ArrayList new_rowids = new ArrayList();
							for(int row=0;row<tnd.rownum;row++)
							{
								long rowid = (long)row;
								if(ROWIDS.Contains(rowid))
								{
									int npage = row / Capacity;
									int offset = row % Capacity;
									int page = (int)pages[npage];
									//br.BaseStream.Position = (page*PageSize)+ContentPageDataOffset+offset*valSize;
									//object data = f.ReadData(br);
									object data = f.ReadData( this.PageReader(page,ContentPageDataOffset+offset*valSize) );
									IComparable o = (IComparable)data;
									IComparable v = (IComparable)val;
								
									if((op=="=")&&(o.CompareTo(v)==0)) {}
									else if((op==">")&&(o.CompareTo(v)>0)) {}
									else if((op=="<")&&(o.CompareTo(v)<0)) {}
									else if((op=="!=")&&(o.CompareTo(v)!=0)) {}
									else if((op==">=")&&(o.CompareTo(v)>=0)) {}
									else if((op=="<=")&&(o.CompareTo(v)<=0)) {}
									else 
										ROWIDS.Remove( rowid );
								}
							}
							if(ROWIDS.Count==0) break;
						}
					}
				}
				else
				{
					Index ndx = this.GetIndex(TableName,flds[0]);
					ROWIDS = new SortedSet( ndx.GetRowSet(false) );
				}
			// Assertion
			if(true)
			{
				Index DELNDX = GetIndex(From_TableName,flds[0]);
				int __rows1 = DELNDX.GetRowCountForKey(false); // non-deleted rows count
				for(int k=1;k<flds.Length;k++)
				{
					if(flds[k].bIndexed)
					{
						Index _NDX = GetIndex(From_TableName,flds[k]);
						if(_NDX.ReverseCount()!=__rows1)
							throw new Exception("Corruption error.");
					}
				}
			}
		}