protected virtual void SetRecord(int x, ref IndexFileRecord r) { int off = NodeOverhead + NodeBase + x * NodeSize; for (int i = 0; i < ColStore; i += 1) { long v = r.Col[i].L; DataType t = Inf.Types[i]; if (t == DataType.String && v == 0) { r.Col[i].L = Database.EncodeString((string)r.Col[i]._O); } else if (t == DataType.Binary && v == 0) { r.Col[i].L = Database.EncodeBinary((byte[])r.Col[i]._O); } int size = DTI.Size(t); ulong p = (ulong)r.Col[i].L; if (t == DataType.Float) { p = Conv.PackFloat(p); } Set(off, p, size); off += size; } }
// For implementation of Alter Table. public void AlterData(ColInfo newcols, int[] map) { // For each record, read the old data, copy the columns, write the new data. // Each column in the new table will either be new, in which case it gets a default value, // or is copied from an old column. The types do not have to match exactly, but need to have the same base type. // Map holds the old colId for eaach new column ( or -1 if it is a new column ). // Doesn't currently check for overflow. long [] oldRow = new long[Cols.Count]; long [] newRow = new long[newcols.Count]; // Initialise newRow to default values. for (int i = 0; i < newRow.Length; i += 1) { newRow[i] = DTI.Default(newcols.Types[i]).L; } int newRowSize = CalcRowSize(newcols); byte [] blank = new byte[newRowSize]; RB = new byte[newRowSize]; // So that old data is not over-written before it has been converted, if new row size is bigger, use descending order. bool desc = newRowSize > RowSize; long id = desc ? RowCount - 1 : 0; // Note : zero based, whereas actual id values are 1-based. long n = RowCount; while (n > 0) { DF.Position = id * RowSize; bool ok = AlterRead(Cols.Types, oldRow); for (int i = 0; i < newRow.Length; i += 1) { int m = map[i]; if (m >= 0) { newRow[i] = oldRow[m]; } } DF.Position = id * newRowSize; if (ok) { AlterWrite(newcols.Types, newRow, newRowSize); } else { DF.Write(blank, 0, blank.Length); } n -= 1; id = desc ? id - 1 : id + 1; } if (!desc) { DF.SetLength(RowCount * newRowSize); } Dirty = true; RowSize = newRowSize; Cols = newcols; }
public int KeySize() { int result = 0; for ( int i = 0; i < KeyCount; i += 1 ) result += DTI.Size( Types[ i ] ); return result; }
public static string DecimalString(long x, DataType t) { decimal d = x; int scale = DTI.Scale(t); d = d / Util.PowerTen(scale); return(d.ToString("F" + scale, System.Globalization.CultureInfo.InvariantCulture)); }
// end Alter section int CalcRowSize(ColInfo c) { int result = 1; // Flag byte that indicates whether row is deleted. for (int i = 1; i < c.Count; i += 1) { result += DTI.Size(c.Type[i]); } return(result); }
public Inserter(Table t, int[] colIx, int idCol, TableExpression te) { T = t; ColIx = colIx; IdCol = idCol; TE = te; DataType [] types = t.Cols.Types; Row = new Value[types.Length]; // The line below is not required as Writer.SaveRecord handles any nulls, but this may be safer. for (int i = 0; i < types.Length; i += 1) { Row[i] = DTI.Default(types[i]); } }
public void AlterTable( string schemaName, string tableName, G.List<AlterAction> alist, Exec e ) { Table t = (Table) GetTable( schemaName, tableName, e ); var names = new G.List<string>( t.Cols.Names ); var types = new G.List<DataType>( t.Cols.Types ); var map = new G.List<int>(); for ( int i = 0; i < names.Count; i += 1 ) map.Add( i ); foreach ( AlterAction aa in alist ) { int ix = names.IndexOf( aa.Name ); if ( aa.Operation != Action.Add && ix == -1 ) e.Error( "Column " + aa.Name + " not found" ); switch ( aa.Operation ) { case Action.Add: if ( ix != -1 ) e.Error( "Column " + aa.Name + " already exists" ); names.Add( aa.Name ); types.Add( aa.Type ); map.Add( 0 ); Sql( "INSERT INTO sys.Column( Table, Name, Type ) VALUES ( " + t.TableId + "," + Util.Quote(aa.Name) + "," + (int)aa.Type + ")" ); break; case Action.Drop: names.RemoveAt( ix ); types.RemoveAt( ix ); map.RemoveAt( ix ); Sql( "DELETE FROM sys.Column WHERE Table = " + t.TableId + " AND Name = " + Util.Quote(aa.Name) ); Sql( "EXEC sys.DroppedColumn(" + t.TableId + "," + ix + ")" ); break; case Action.ColumnRename: names.RemoveAt( ix ); names.Insert( ix, aa.NewName ); Sql( "UPDATE sys.Column SET Name = " + Util.Quote(aa.NewName) + " WHERE Table=" + t.TableId + " AND Name = " + Util.Quote(aa.Name) ); break; case Action.Modify: if ( DTI.Base( aa.Type ) != DTI.Base( types[ ix ] ) ) e.Error( "Modify cannot change base type" ); if ( DTI.Scale( aa.Type ) != DTI.Scale( types[ ix ] ) ) e.Error( "Modify cannot change scale" ); types.RemoveAt( ix ); types.Insert( ix, aa.Type ); Sql( "UPDATE sys.Column SET Type = " + (int)aa.Type + " WHERE Table=" + t.TableId + " AND Name = " + Util.Quote(aa.Name) ); Sql( "EXEC sys.ModifiedColumn(" + t.TableId + "," + ix + ")" ); break; } } var newcols = ColInfo.New( names, types ); t.AlterData( newcols, map.ToArray() ); Sql( "EXEC sys.RecreateModifiedIndexes()" ); t.OpenIndexes(); ResetCache(); }
public ColInfo(string [] names, DataType[] types) { Names = names; Types = types; Count = Types.Length; Sizes = new byte[Count]; for (int i = 0; i < Count; i += 1) { Sizes[i] = (byte)DTI.Size(Types[i]); } }
public static string ToString(Value x, DataType t) { t = DTI.Base(t); return (t == DataType.Bigint ? x.L.ToString() : t == DataType.String ? "'" + x.S + "'" : t == DataType.Double ? x.D.ToString() : t == DataType.Bool ? x.B.ToString() : t == DataType.Binary ? Util.ToString(x.X) : DecimalString(x.L, t)); }
public static string ToHtml(Value x, DataType t) { t = DTI.Base(t); return (t == DataType.Bigint ? x.L.ToString() : t == DataType.String ? HtmlEncode((string)x._O) : t == DataType.Double ? x.D.ToString() : t == DataType.Bool ? x.B.ToString() : t == DataType.Binary ? Util.ToString((byte[])x._O) : DecimalString(x.L, t)); }
public Inserter(Table t, int[] colIx, int idCol, TableExpression te) { T = t; ColIx = colIx; IdCol = idCol; TE = te; DataType [] types = t.CI.Type; Row = new Value[types.Length]; // Initialise row to default values. for (int i = 0; i < types.Length; i += 1) { Row[i] = DTI.Default(types[i]); } }
bool AlterRead(DataType [] types, long [] row) { int ix; byte [] RowBuffer = DataFile.FastRead(RowSize, out ix); if (RowBuffer[ix++] == 0) { return(false); // Row has been deleted } for (int i = 1; i < types.Length; i += 1) { DataType t = types[i]; int size = DTI.Size(t); long x = Util.Get(RowBuffer, ix, size, t); ix += size; row[i] = x; } return(true); }
protected virtual void GetRecord(int x, ref IndexFileRecord r) { if (r.Col == null) { r.Col = new Value[ColStore]; } int off = NodeOverhead + NodeBase + x * NodeSize; for (int i = 0; i < ColStore; i += 1) { DataType t = Inf.Types[i]; int size = DTI.Size(t); ulong u = Get(off, size); off += size; if (t == DataType.Float) { u = Conv.UnpackFloat((uint)u); } else if (t == DataType.Int) { u = (ulong)(long)(int)(uint)u; } else if (t == DataType.Smallint) { u = (ulong)(long)(short)(ushort)u; } else if (t == DataType.Tinyint) { u = (ulong)(long)(sbyte)(byte)u; } r.Col[i].L = (long)u; if (t == DataType.String) { r.Col[i]._O = Database.DecodeString((long)u); } else if (t == DataType.Binary) { r.Col[i]._O = Database.DecodeBinary((long)u); } } }
void AlterWrite(DataType [] types, long [] row, int newRowSize) { RowBuffer[0] = 1; int ix = 1; for (int i = 1; i < types.Length; i += 1) { DataType t = types[i]; long x = row[i]; if (t == DataType.Float) { x = Conv.PackFloat(x); } int size = DTI.Size(t); Util.Set(RowBuffer, ix, x, size); ix += size; } DataFile.Write(RowBuffer, 0, newRowSize, false); }
protected virtual void GetRecord(int x, ref IndexFileRecord r) { if (r.Col == null) { r.Col = new Value[ColStore]; } int off = NodeOverhead + NodeBase + x * NodeSize; for (int i = 0; i < ColStore; i += 1) { DataType t = Inf.Types[i]; int size = DTI.Size(t); long v = Util.Get(Data, off, size, t); off += size; r.Col[i].L = v; if (t <= DataType.String) { r.Col[i]._O = Database.Decode(v, t); } } }
void InitColumnInfo(ColInfo ci) { CI = ci; int count = ci.Count; AllCols = Util.OneToN(count - 1); Size = new byte[count]; Offset = new int[count]; int offset = -8; // -8 to allow for the Id column not being stored. for (int i = 0; i < count; i += 1) { Size[i] = (byte)DTI.Size(CI.Type[i]); Offset[i] = offset; offset += Size[i]; } RowSize = 1 + offset; // +1 is for byte that indicates whether row exists. RowCount = DataFile.Length / RowSize; RowBuffer = new byte[RowSize]; }
protected virtual void SetRecord(int x, ref IndexFileRecord r) { int off = NodeOverhead + NodeBase + x * NodeSize; for (int i = 0; i < ColStore; i += 1) { DataType t = Inf.Types[i]; if (t <= DataType.String && r.Col[i].L == 0) { r.Col[i].L = Database.Encode(r.Col[i]._O, t); } int size = DTI.Size(t); long p = r.Col[i].L; if (t == DataType.Float) { p = Conv.PackFloat(p); } Set(off, (ulong)p, size); off += size; } }