Ejemplo n.º 1
0
		/// <summary>
		/// Adds a field
		/// </summary>
		public void AddField(string TableName, Field f)
		{	
			lock(this.TableBlocking)// Total blocking required
			{

				string tbl = TableName;
				QueryCacheDestroy(TableName);
				Field[] flds = GetFields(TableName);
				foreach(Field i in flds)
				{
					if(f.Name==i.Name)
						throw new Exception("Column already present.");
				}
				//FieldsCache[TableName]=null; // cancel Field Cache
				int tid = (int)this.TableName2TID[TableName];
				TableNameDef tnd = this.TID2Def[tid] as TableNameDef;
				try
				{
					// auto increment field seq
					int fseq = tnd.fseq++;
					this.fsDB.Position = tnd.PageOfTableDef * PageSize;
					this.fsDB.Position += 1; // skip delete
					this.fsDB.Position += 1; // skip type
					this.fsDB.Position += 4; // skip fid
					bw.Write( tnd.fseq );
					bw.Flush();

					// build page
					int page = this.LockAvaiblePage();
					this.fsDB.Position = page*PageSize;
					bw.Write( (bool)true ); // deleted
					bw.Flush();
					bw.Write( (byte)FieldPageType ); 
					bw.Write( tid );
					f.seq=fseq;
					f.tid=tid;
					f.Write(bw);
					bw.Flush();
					f.PageOfFieldSef=page;
					f.DataFID = new ArrayList();
					this.fsDB.Position = page*PageSize;
					bw.Write( (bool)false ); // active
					bw.Flush();
					tnd.fseq2FieldDef[f.seq]=f;
					PeekPagesByFID(tid).Add(page);

					// grow if it is needed
					if(tnd.rownum>0)
					{
						int valSize = (int)f.DataSize();
						long Capacity = (PageSize-ContentPageDataOffset)/valSize;
						ArrayList pages = f.DataFID;
						while((pages.Count*Capacity)<tnd.rownum)
						{
							int datapage = this.LockAvaiblePage();
							bw.BaseStream.Position = (datapage*PageSize);
							bw.Write( true );
							bw.Flush();
							bw.Write( (byte)Database.ContentPageType );
							bw.Write( tnd.TableFID );
							bw.Write( (int)f.seq );
							bw.Write( f.DataFID.Count );
							bw.Flush();
							for(int c=0;c<Capacity;c++)
							{
								bw.BaseStream.Position = (datapage*PageSize)+ContentPageDataOffset+c*valSize;
								f.WriteDefaultData(bw,false);
							}
							bw.Flush();
							bw.BaseStream.Position = (datapage*PageSize);
							bw.Write( (bool)false );
							bw.Flush();
							pages.Add(datapage);
							PeekPagesByFID(tid).Add(datapage);
							this.InvalidatePage(datapage);
						}
					}
				}
				catch(Exception ex)
				{
					this.LogToFile(ex.Message,ex.StackTrace);
					throw new Exception("Unhandled exception at AddField.");
				}
			}
			
		}