public virtual bool IsEquivalent(libobj obj) { if (!db_structure.IsAutoupdate(this) || !db_structure.IsAutoupdate(obj)) { return(this == obj); } return(IsEquivalent(this.get_values_for_db(), obj.get_values_for_db())); //PropertyInfo[] ps = db_structure.PropertiesToBeUpdated(this); //data_type[] datatypes = db_structure.GetDataTypes(this); //bool[] writable = db_structure.GetIsWritable(this); //for (int i = 0; i < ps.Length; i++) //{ // if (!writable[i]) continue; //Readonly field should not be changed // if (is_same(datatypes[i], ps[i].GetValue(this, null), ps[i].GetValue(this.old_values, null))) // continue; // else // return false; //} //return true; }
public virtual libobj Clone() { libobj o = (libobj)System.Activator.CreateInstance(this.GetType()); o.Fill(this.ID, false); return(o); }
public virtual void Update() { if (!db_structure.IsAutoupdate(this)) { return; } if (this.ID == 0) { throw new Exception("The record does not exist in database; try Insert() instead of Update()"); } ArrayList oldv = old_values.get_values_for_db(); ArrayList newv = get_values_for_db(); if (IsEquivalent(oldv, newv)) //nothing changed; no update needed { return; } string sql = make_update_sql(newv); if (string.IsNullOrEmpty(sql)) { return; } Database.ExecuteNonQuery(sql); Database.WriteLog(sql, old_values.make_update_sql(oldv)); old_values = Clone(); }
public virtual void Insert() { if (!db_structure.IsAutoupdate(this)) { return; } if (this.ID != 0) { throw new Exception(string.Format( "id = {0} on {1} already exists; insert failed", this.ID, this.GetType().Name)); } string sql = make_insert_sql(); if (string.IsNullOrEmpty(sql)) { return; } Database.ExecuteNonQuery(sql); this.ID = Database.LastInsertRowID(); Database.WriteLog(sql, make_delete_sql()); old_values = Clone(); }
/// <summary> /// Remove the readonly member of the list /// </summary> /// <param name="obj"></param> /// <param name="list"></param> /// <returns></returns> public static string[] CleanUpForWrite(libobj obj, string[] list) { List <string> newlist = new List <string>(list.Length); for (int i = 0; i < list.Length; i++) { if (GetIsWritable(obj)[i]) { newlist.Add(list[i]); } } return(newlist.ToArray()); }
public static bool IsAutoupdate(libobj obj) { Type type = obj.GetType(); string name = type.Name; table_info t; if (!_tables.ContainsKey(name)) { AutoUpdateClassAttribute[] attr = (AutoUpdateClassAttribute[]) type.GetCustomAttributes(typeof(AutoUpdateClassAttribute), false); t = new table_info(); if (attr.Length > 0) //class labeled as autoupde-able { PropertyInfo[] props = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.Instance); AutoUpdatePropAttribute[] attrs; List <PropertyInfo> updateable_props = new List <PropertyInfo>(); System.Array.ForEach <PropertyInfo>(props, (p) => { attrs = (AutoUpdatePropAttribute[])p.GetCustomAttributes( typeof(AutoUpdatePropAttribute), false); if (attrs.Length > 0) { updateable_props.Add(p); } }); // if no property is labeled to be updated to a specific field (i.e. updateable_prop.count == 0) // then there is nothing to update; thus only populate table_info if necc. if (!(updateable_props.Count == 0)) { t.ClassAttr = attr[0]; t.PropertyInfos = updateable_props.ToArray(); } } //end if (attr.Length > 0) //class labeled as autoupde-able _tables.Add(name, t); } else //if (!_tables.ContainsKey(name)) { _tables.TryGetValue(name, out t); } //end if (!_tables.ContainsKey(name)) return(t.ClassAttr != null); }
private static table_info get_table_info(libobj obj) { return(get_table_info(obj.GetType().Name)); }
public static ConversionHandler[] GetConversionHandlers(libobj obj) { return(get_table_info(obj).ConversioHandlers); }
public static bool[] GetIsWritable(libobj obj) { return(get_table_info(obj).Writable); }
public static data_type[] GetDataTypes(libobj obj) { return(get_table_info(obj).DataTypes); }
public static string[] GetFieldNames(libobj obj) { return(get_table_info(obj).FieldNames); }
public static PropertyInfo[] PropertiesToBeUpdated(libobj obj) { return(get_table_info(obj).PropertyInfos); }
public static string GetTableName(libobj obj) { return(System.Enum.GetName(typeof(Tables), GetTable(obj))); }
public static Tables GetTable(libobj obj) { return(get_table_info(obj).ClassAttr.AssociatedTable); }
// the "createClone" param is to avoid infinite loop... private void Fill(int id, bool createClone) { if (!db_structure.IsAutoupdate(this)) { return; } if (!Exists(db_structure.GetTable(this), id)) { this.ID = 0; return; //throw new Exception(string.Format( // "id = {0} in {1} is not found; Fill() failed", // id, db_structure.GetTableName(this))); } // make sql query string... string str = String.Format("SELECT {2} FROM {0} WHERE id = {1}", db_structure.GetTableName(this), id, string.Join(",", db_structure.GetFieldNames(this))); try { // get values from db ArrayList values = Database.GetFirstRow(str); ConversionHandler[] handler = (db_structure.GetConversionHandlers(this)); PropertyInfo[] ps = db_structure.PropertiesToBeUpdated(this); object outv; // try type casting to the properties for (int i = 0; i < values.Count; i++) { //try the specific conversion handler first if (handler[i] != null && (handler[i].Invoke(this, values[i], out outv, false) == 0)) { ps[i].SetValue(this, outv, null); continue; } //otherwise try generalized method below if (convert_from_db_datatype(ps[i].PropertyType.ToString(), values[i], out outv) != 0) { //conversion fails throw new Exception(string.Format( "Data type conversion from {1} failed", ps[i].PropertyType.ToString())); } ps[i].SetValue(this, outv, null); } this.ID = id; if (createClone) { this.old_values = Clone(); } } catch (SqliteClient.SQLiteException e) { throw new Exception("Database connection returns error", e); } }