public DbRef GetEmptyRef(String tableName) { DbRef r; if (!_emptyRefs.TryGetValue(tableName, out r)) { r = new DbRef(tableName, Guid.Empty); _emptyRefs.Add(tableName, r); } return r; }
public IEntity GetObject(DbRef r) { EntityType t; if (!_types.TryGetValue(r.TableName, out t)) { t = EntityFactory.FindType(r.TableName); _types.Add(r.TableName, t); } return _db.SelectById(t, r.ToString(CultureInfo.InvariantCulture)); }
public DbRef GetRef(String tableName, Guid id) { DbRef r; if (id.Equals(Guid.Empty)) r = GetEmptyRef(tableName); else { if (!_refs.TryGetValue(id, out r)) { r = new DbRef(tableName, id); _refs.Add(id, r); } } return r; }
public void RollbackTransaction() { var toRemoveFromCache = new List <Guid>(); var modified = new Dictionary <string, List <string> >(); var inserted = new Dictionary <string, List <string> >(); Exec(string.Format("SELECT [Id], [TableName], [Status] FROM {0} ORDER BY [TableName]", TranStatusTable), cmd => { using (SqliteDataReader r = cmd.ExecuteReader()) { while (r.Read()) { String id = r.GetString(0); String tableName = r.GetString(1); Operation status = (Operation)r.GetInt16(2); Dictionary <String, List <String> > dict = status != Operation.Insert ? modified : inserted; List <String> ids; if (!dict.TryGetValue(tableName, out ids)) { ids = new List <string>(); dict.Add(tableName, ids); } ids.Add(id); } } }); using (SqliteTransaction tran = ActiveConnection.BeginTransaction()) { try { foreach (KeyValuePair <String, List <String> > pair in modified) { String ids = ""; foreach (String s in pair.Value) { ids = ids + (String.IsNullOrEmpty(ids) ? String.Format("'{0}'", s) : String.Format(",'{0}'", s)); toRemoveFromCache.Add(DbRef.FromString(s).Id); } Exec(string.Format("INSERT OR REPLACE INTO _{0} SELECT * FROM __{0} WHERE [Id] IN ({1})", pair.Key, ids) , cmd => { cmd.Transaction = tran; cmd.ExecuteNonQuery(); }); Exec(string.Format("DELETE FROM __{0}", pair.Key), cmd => { cmd.Transaction = tran; cmd.ExecuteNonQuery(); }); } foreach (KeyValuePair <String, List <String> > pair in inserted) { string ids = ""; foreach (string s in pair.Value) { ids = ids + (String.IsNullOrEmpty(ids) ? String.Format("'{0}'", s) : String.Format(",'{0}'", s)); toRemoveFromCache.Add(DbRef.FromString(s).Id); } Exec(string.Format("DELETE FROM _{0} WHERE [Id] IN ({1})", pair.Key, ids), cmd => { cmd.Transaction = tran; cmd.ExecuteNonQuery(); }); } Exec(string.Format("DELETE FROM {0}", TranStatusTable), cmd => { cmd.Transaction = tran; cmd.ExecuteNonQuery(); }); tran.Commit(); _cache.Clear(toRemoveFromCache); } catch { tran.Rollback(); throw; } } }
private void ProcessAllInternal(IEnumerable <IEntity> data, ProcessMode mode, SqliteTransaction tran, bool inTran) { string[] columns = null; var cmd = new SqliteCommand[4]; String tableName = null; lock (_dbsync) try { foreach (IEntity obj in data) { if (cmd[(int)Operation.Insert] == null) { IEntityType type = obj.EntityType; columns = GetColumns(type); String fNames = ""; String fParameters = ""; String fFields = ""; foreach (string column in columns) { if (!String.IsNullOrEmpty(fNames)) { fNames = fNames + ","; fParameters = fParameters + ","; fFields = fFields + ","; } fNames = fNames + column; fParameters = fParameters + "@" + column; fFields = fFields + String.Format("[{0}] = @{0}", column); } fNames = fNames + ",IsTombstone,IsDirty"; fParameters = fParameters + ",@IsTombstone,@IsDirty"; fFields = fFields + ",[IsTombstone] = @IsTombstone, [IsDirty] = @IsDirty"; tableName = type.TableName; cmd[(int)Operation.Insert] = new SqliteCommand(String.Format("INSERT INTO [_{0}]({1}) VALUES({2})", tableName, fNames, fParameters), ActiveConnection, tran); cmd[(int)Operation.Update] = new SqliteCommand(String.Format("UPDATE [_{0}] SET {1} WHERE [Id] = @Id", tableName, fFields), ActiveConnection, tran); foreach (string column in columns) { cmd[0].Parameters.Add("@" + column, _supportedTypes[GetType(type.GetPropertyType(column))].DbType); cmd[1].Parameters.Add("@" + column, _supportedTypes[GetType(type.GetPropertyType(column))].DbType); } cmd[(int)Operation.Insert].Parameters.Add("@IsTombstone", DbType.Boolean); cmd[(int)Operation.Insert].Parameters.Add("@IsDirty", DbType.Boolean); cmd[(int)Operation.Update].Parameters.Add("@IsTombstone", DbType.Boolean); cmd[(int)Operation.Update].Parameters.Add("@IsDirty", DbType.Boolean); cmd[(int)Operation.Select] = new SqliteCommand(String.Format("SELECT Id FROM [_{0}] WHERE [Id] = @Id", tableName), ActiveConnection, tran); cmd[(int)Operation.Select].Parameters.Add("@Id", DbType.String); cmd[(int)Operation.Delete] = new SqliteCommand(String.Format("DELETE FROM [_{0}] WHERE [Id] = @Id", tableName), ActiveConnection, tran); cmd[(int)Operation.Delete].Parameters.Add("@Id", DbType.String); } //row id DbRef id; if (mode == ProcessMode.InitialLoad || mode == ProcessMode.ServerChanges) { id = DbRef.CreateInstance(tableName, ((ISqliteEntity)obj).EntityId); } else { id = (DbRef)obj.GetValue(obj.EntityType.IdFieldName); } Operation operation = Operation.Insert; //insert if (mode != ProcessMode.InitialLoad) { if (((ISqliteEntity)obj).IsTombstone) { operation = mode == ProcessMode.ServerChanges ? Operation.Delete : Operation.Update; } else { cmd[2].Parameters[0].Value = id; if (cmd[2].ExecuteScalar() != null) { operation = Operation.Update; //update } } } //assign values if (operation == Operation.Delete) //delete { cmd[(int)operation].Parameters[0].Value = id; } else { int n = 0; foreach (string column in columns) { cmd[(int)operation].Parameters[n].Value = obj.GetValue(column); n++; } cmd[(int)operation].Parameters[n].Value = ((ISqliteEntity)obj).IsTombstone ? 1 : 0; //IsTombstone var entity = (ISqliteEntity)obj; cmd[(int)operation].Parameters[n + 1].Value = mode == ProcessMode.LocalChanges && (entity.IsNew() || entity.IsModified()) ? 1 : 0; //isDirty } if (mode == ProcessMode.LocalChanges && inTran) { CopyTranObject(tran, tableName, id.ToString(), operation); } cmd[(int)operation].ExecuteNonQuery(); } } finally { foreach (var c in cmd) { if (c != null) { c.Dispose(); } } } }
private IEnumerable <IEntity> Select(IEntityType type, bool useView, String where, params object[] arguments) { lock (_dbsync) { string[] columns = GetColumns(type); int n; String cmdKey = type.Name + where + useView; SqliteCommand cmd; if (!_commands.TryGetValue(cmdKey, out cmd)) { String tableName = type.TableName; String columnNames = ""; // ReSharper disable once LoopCanBeConvertedToQuery foreach (string column in columns) { columnNames = columnNames + string.Format("{0}{1}", string.IsNullOrEmpty(columnNames) ? "" : ",", column); } if (!useView) { columnNames = columnNames + ",IsTombstone"; } columnNames = columnNames + ",IsDirty"; cmd = new SqliteCommand { Connection = ActiveConnection, CommandText = String.Format("SELECT {0} FROM [{1}]{2}", columnNames, useView ? tableName : "_" + tableName, String.IsNullOrEmpty(@where) ? "" : " " + @where) }; n = 1; foreach (object p in arguments) { cmd.Parameters.AddWithValue(String.Format("@p{0}", n), p); n++; } cmd.Prepare(); _commands.Add(cmdKey, cmd); } else { for (int i = 0; i < arguments.Length; i++) { cmd.Parameters[i].Value = arguments[i]; } } var list = new List <IEntity>(); using (SqliteDataReader r = cmd.ExecuteReader()) { if (r.HasRows) { while (r.Read()) { IEntity entity = EntityFactory.CreateInstance(type); n = 0; foreach (string column in columns) { Type t = type.GetPropertyType(column); if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>)) { t = Nullable.GetUnderlyingType(t); } object value = r[n]; if (value is DBNull) { value = null; } else { if (t == typeof(IDbRef)) { value = DbRef.FromString(value.ToString()); } else { if (t == typeof(Guid)) { Guid g; if (!Guid.TryParse(value.ToString(), out g)) { if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>)) { value = null; } else { throw new ArgumentException(String.Format("Can't convert value '{0}' to System.Guid", value)); } } else { value = g; } } else { value = Convert.ChangeType(value, t); } } } entity.SetValue(column, value); n++; } bool isTombstone = !useView && (long)r["IsTombstone"] != 0; var sqliteEntity = (ISqliteEntity)entity; sqliteEntity.IsTombstone = isTombstone; sqliteEntity.Load((long)r["IsDirty"] != 0); list.Add(entity); } } } return(list); } }
public IDbRef CreateDbRef(string tableName, Guid id) { return(DbRef.CreateInstance(tableName, id)); }