// Get a catalog value by entry from database or catalog public TypedValue GetValue(CatalogEntry entry) { if (entry.IsDatabase) { if (_catalog.SqlFlag) { // Database sql comes from external table var table = DataTableSql.Create(entry.Name, entry.DataType.Heading); return(RelationValue.Create(table)); } else if (!entry.IsLoaded) // lazy load // Database non-sql lazy loaded from store on path, then in catalog { var value = Persist.Create(_catalog.DatabasePath, true).Load(entry.Name); if (entry.DataType != value.DataType) { throw ProgramError.Fatal("Catalog", "Type mismatch for variable {0}", entry.Name); } entry.IsLoaded = true; return(Persist.Create(_catalog.DatabasePath, true).Load(entry.Name)); } } // Non-database exists only in the catalog return(entry.Value); }
public DataRow MakeEntry(CatalogEntry entry) { return(DataRow.Create(Table.Heading, new TypedValue[] { TextValue.Create(entry.Name), TextValue.Create(entry.Kind.ToString()), TextValue.Create(entry.DataType.BaseType.Name), BinaryValue.Create(entry.ToBinary()) })); }
// Store new entry to catalog, perhaps removing old value first // Currently only for Sql -- Local does total dump internal void StoreEntry(CatalogEntry entry, CatalogEntry oldentry = null) { var ctm = CatalogTableMaker.Create(_catalogtableheading); if (SqlFlag) { var table = DataTableSql.Create(CatalogTableName, _catalogtableheading); if (oldentry != null) { var ctmx = CatalogTableMaker.Create(_catalogtableheading); ctmx.Table.AddRow(ctmx.MakeEntry(oldentry)); table.UpdateJoin(ctmx.Table, JoinOps.MINUS); } ctm.Table.AddRow(ctm.MakeEntry(entry)); table.UpdateJoin(ctm.Table, JoinOps.UNION); } }
// set entry to value, update as needed internal void SetValue(CatalogEntry entry, TypedValue value) { // Choose where to store and whether to convert TypedValue finalvalue; if (entry.IsDatabase && _catalog.SqlFlag) { // Database + sql => hand it to sql, to create table if needed // set a default value to carry the type DataTableSql.Create(entry.Name, value.AsTable()); finalvalue = value.DataType.DefaultValue(); } else { // everything else stored in catalog if (value.DataType is DataTypeRelation) { finalvalue = RelationValue.Create(DataTableLocal.Convert(value.AsTable())); } else { finalvalue = value; } // set flags for persisting if (entry.IsPersistent) { entry.IsUnsaved = true; entry.IsLoaded = true; } } // store value if changed if (finalvalue != entry.Value) { var oldvalue = (entry.Value == null) ? null : entry; entry.Set(finalvalue); if (entry.IsPersistent && _catalog.SaveFlag) { _catalog.StoreEntry(entry, oldvalue); } } }
public void LoadFromTable() { Logger.WriteLine(2, "Load catalog for '{0}'", DatabaseName); var centry = GlobalVars.FindEntry(CatalogTableName); var table = GlobalVars.GetValue(centry).AsTable(); foreach (var row in table.GetRows()) { var blob = (row.Values[3] as BinaryValue).Value; // BUG: argLess is an attribute of a symbol but not of an ExpressionBlock, so does not round trip var entry = CatalogEntry.FromBinary(blob); PersistentVars.Add(entry); if (entry.IsDatabase) { if (!LinkRelvar(entry.Name)) { throw ProgramError.Fatal("Catalog", "cannot add '{0}'", entry.Name); } } } }
// Add new catalog entry to proper scope // Risky: caller may not know where it went; maybe merge Global & Persistent? internal void AddEntry(string name, DataType datatype, EntryKinds kind, EntryFlags flags = EntryFlags.None, TypedValue value = null) { var scope = (flags.HasFlag(EntryFlags.Persistent)) ? _catalog.PersistentVars : this; var entry = new CatalogEntry { Name = name, DataType = datatype, Kind = kind, Flags = flags, Scope = scope, Value = value, }; scope.Add(entry); // update catalog if (flags.HasFlag(EntryFlags.Persistent) && _catalog.SaveFlag) { Logger.Assert(entry.Kind == EntryKinds.Type || entry.Value == null, entry); if (entry.Kind == EntryKinds.Type) { _catalog.StoreEntry(entry); } } }
// Add a named entry internal void Add(CatalogEntry entry) { _entries[entry.Name] = entry; }