예제 #1
0
 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;
 }
예제 #2
0
 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));
 }
예제 #3
0
 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;
 }
예제 #4
0
        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;
                }
            }
        }
예제 #5
0
        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();
                        }
                    }
                }
        }
예제 #6
0
        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);
            }
        }
예제 #7
0
 public IDbRef CreateDbRef(string tableName, Guid id)
 {
     return(DbRef.CreateInstance(tableName, id));
 }