Ejemplo n.º 1
0
        internal StatementImpl(sqlite3_stmt stmt, SQLiteDatabaseConnection db)
        {
            this.stmt = stmt;
            this.db   = db;

            this.bindParameters = new BindParameterOrderedDictionaryImpl(this);
            this.columns        = new ColumnsListImpl(this);
            this.current        = new ResultSetImpl(this);

            this.dbDisposing   = (o, e) => this.Dispose();
            this.db.Disposing += dbDisposing;
        }
Ejemplo n.º 2
0
        public void Initialize(IUserManager userManager, SemaphoreSlim dbLock, SQLiteDatabaseConnection dbConnection)
        {
            WriteLock.Dispose();
            WriteLock = dbLock;
            WriteConnection?.Dispose();
            WriteConnection = dbConnection;

            using (var connection = GetConnection())
            {
                var userDatasTableExists = TableExists(connection, "UserDatas");
                var userDataTableExists  = TableExists(connection, "userdata");

                var users = userDatasTableExists ? null : userManager.Users;

                connection.RunInTransaction(
                    db =>
                {
                    db.ExecuteAll(string.Join(';', new[]
                    {
                        "create table if not exists UserDatas (key nvarchar not null, userId INT not null, rating float null, played bit not null, playCount int not null, isFavorite bit not null, playbackPositionTicks bigint not null, lastPlayedDate datetime null, AudioStreamIndex INT, SubtitleStreamIndex INT)",

                        "drop index if exists idx_userdata",
                        "drop index if exists idx_userdata1",
                        "drop index if exists idx_userdata2",
                        "drop index if exists userdataindex1",
                        "drop index if exists userdataindex",
                        "drop index if exists userdataindex3",
                        "drop index if exists userdataindex4",
                        "create unique index if not exists UserDatasIndex1 on UserDatas (key, userId)",
                        "create index if not exists UserDatasIndex2 on UserDatas (key, userId, played)",
                        "create index if not exists UserDatasIndex3 on UserDatas (key, userId, playbackPositionTicks)",
                        "create index if not exists UserDatasIndex4 on UserDatas (key, userId, isFavorite)"
                    }));

                    if (userDataTableExists)
                    {
                        var existingColumnNames = GetColumnNames(db, "userdata");

                        AddColumn(db, "userdata", "InternalUserId", "int", existingColumnNames);
                        AddColumn(db, "userdata", "AudioStreamIndex", "int", existingColumnNames);
                        AddColumn(db, "userdata", "SubtitleStreamIndex", "int", existingColumnNames);

                        if (!userDatasTableExists)
                        {
                            ImportUserIds(db, users);

                            db.ExecuteAll("INSERT INTO UserDatas (key, userId, rating, played, playCount, isFavorite, playbackPositionTicks, lastPlayedDate, AudioStreamIndex, SubtitleStreamIndex) SELECT key, InternalUserId, rating, played, playCount, isFavorite, playbackPositionTicks, lastPlayedDate, AudioStreamIndex, SubtitleStreamIndex from userdata where InternalUserId not null");
                        }
                    }
                },
                    TransactionMode);
            }
        }
Ejemplo n.º 3
0
        public void Dispose()
        {
            if (_disposed)
            {
                return;
            }

            _writeLock.Release();

            _db       = null; // Don't dispose it
            _disposed = true;
        }
Ejemplo n.º 4
0
        public static void RunQueries(this SQLiteDatabaseConnection connection, string[] queries)
        {
            if (queries == null)
            {
                throw new ArgumentNullException(nameof(queries));
            }

            connection.RunInTransaction(conn =>
            {
                conn.ExecuteAll(string.Join(";", queries));
            });
        }
Ejemplo n.º 5
0
        public static void Attach(SQLiteDatabaseConnection db, string path, string alias)
        {
            var commandText = string.Format(
                CultureInfo.InvariantCulture,
                "attach @path as {0};",
                alias);

            using (var statement = db.PrepareStatement(commandText))
            {
                statement.TryBind("@path", path);
                statement.MoveNext();
            }
        }
        /// <summary>
        /// Returns the filename associated with the database.
        /// </summary>
        /// <param name="This">The database connection.</param>
        /// <param name="database">The database name. The main database file has the name "main".</param>
        /// <returns>The attached database's filename.</returns>
        /// <exception cref="InvalidOperationException">If the database is not attached, temporary, or in memory.</exception>
        public static string GetFileName(this SQLiteDatabaseConnection This, string database)
        {
            Contract.Requires(This != null);

            string filename;

            if (This.TryGetFileName(database, out filename))
            {
                return(filename);
            }

            throw new InvalidOperationException("Database is either not attached, temporary or in memory");
        }
Ejemplo n.º 7
0
        public static void RunQueries(this SQLiteDatabaseConnection connection, string[] queries)
        {
            if (queries == null)
            {
                throw new ArgumentNullException("queries");
            }

            connection.RunInTransaction(conn =>
            {
                //foreach (var query in queries)
                //{
                //    conn.Execute(query);
                //}
                conn.ExecuteAll(string.Join(";", queries));
            });
        }
Ejemplo n.º 8
0
        /// <summary>
        /// After the response from server, we need to update IsDirty for all entities
        /// </summary>
        internal void UpdateDirtyTrackingEntities(Type ty, List <SQLiteOfflineEntity> entities)
        {
            using (SQLiteDatabaseConnection connection = SQLitePCL.pretty.SQLite3.Open(localFilePath))
            {
                // Get mapping from my type
                var map = manager.GetMapping(ty);
                var queryUpdateDirtyTracking = String.Format(SQLiteConstants.UpdateDirtyTracking, map.TableName);

                connection.RunInTransaction((conn) =>
                {
                    try
                    {
                        foreach (var entity in entities)
                        {
                            // Set Values for tracking table
                            var parameters = new object[5];
                            parameters[0]  = P(entity.ServiceMetadata.IsTombstone);
                            parameters[1]  = P(0);
                            parameters[2]  = P(entity.ServiceMetadata.ETag);


                            var editUri = String.Empty;
                            if (entity.ServiceMetadata.EditUri != null && entity.ServiceMetadata.EditUri.IsAbsoluteUri)
                            {
                                editUri = entity.ServiceMetadata.EditUri.AbsoluteUri;
                            }

                            parameters[3] = P(editUri);
                            parameters[4] = P(entity.ServiceMetadata.Id);

                            conn.Execute(queryUpdateDirtyTracking, parameters);
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.Message);
                        throw;
                    }
                });
            }
        }
Ejemplo n.º 9
0
        protected ManagedConnection GetConnection(bool _ = false)
        {
            WriteLock.Wait();
            if (WriteConnection != null)
            {
                return(new ManagedConnection(WriteConnection, WriteLock));
            }

            WriteConnection = SQLite3.Open(
                DbFilePath,
                DefaultConnectionFlags | ConnectionFlags.Create | ConnectionFlags.ReadWrite,
                null);

            if (CacheSize.HasValue)
            {
                WriteConnection.Execute("PRAGMA cache_size=" + CacheSize.Value);
            }

            if (!string.IsNullOrWhiteSpace(JournalMode))
            {
                WriteConnection.Execute("PRAGMA journal_mode=" + JournalMode);
            }

            if (Synchronous.HasValue)
            {
                WriteConnection.Execute("PRAGMA synchronous=" + (int)Synchronous.Value);
            }

            if (PageSize.HasValue)
            {
                WriteConnection.Execute("PRAGMA page_size=" + PageSize.Value);
            }

            WriteConnection.Execute("PRAGMA temp_store=" + (int)TempStore);

            // Configuration and pragmas can affect VACUUM so it needs to be last.
            WriteConnection.Execute("VACUUM");

            return(new ManagedConnection(WriteConnection, WriteLock));
        }
Ejemplo n.º 10
0
 public ManagedConnection(SQLiteDatabaseConnection db)
 {
     this.db = db;
 }
Ejemplo n.º 11
0
 public ManagedConnection(SQLiteDatabaseConnection db, SemaphoreSlim writeLock)
 {
     _db        = db;
     _writeLock = writeLock;
 }
Ejemplo n.º 12
0
        protected ManagedConnection CreateConnection(bool isReadOnly = false)
        {
            if (_connection != null)
            {
                return(_connection);
            }

            lock (WriteLock)
            {
                if (!_versionLogged)
                {
                    _versionLogged = true;
                    _logger.LogInformation("SQLite version: {Version}", SQLite3.Version);
                    _logger.LogInformation("SQLite compiler options: {Options}", string.Join(',', SQLite3.CompilerOptions));
                }

                ConnectionFlags connectionFlags;

                if (isReadOnly)
                {
                    // TODO: set connection flags correctly
                    // connectionFlags = ConnectionFlags.ReadOnly
                    _logger.LogDebug("Opening read connection to database");
                    connectionFlags  = ConnectionFlags.Create;
                    connectionFlags |= ConnectionFlags.ReadWrite;
                }
                else
                {
                    _logger.LogDebug("Opening write connection to database.");
                    connectionFlags  = ConnectionFlags.Create;
                    connectionFlags |= ConnectionFlags.ReadWrite;
                }

                if (EnableSingleConnection)
                {
                    connectionFlags |= ConnectionFlags.PrivateCache;
                }
                else
                {
                    connectionFlags |= ConnectionFlags.SharedCached;
                }

                connectionFlags |= ConnectionFlags.NoMutex;

                var db = SQLite3.Open(DbFilePath, connectionFlags, null);

                try
                {
                    if (string.IsNullOrWhiteSpace(_defaultWal))
                    {
                        _defaultWal = db.Query("PRAGMA journal_mode").SelectScalarString().First();

                        _logger.LogInformation("Default journal_mode for {0} is {1}", DbFilePath, _defaultWal);
                    }

                    var queries = new List <string>
                    {
                        // "PRAGMA cache size=-10000"
                        // "PRAGMA read_uncommitted = true",
                        "PRAGMA synchronous=Normal"
                    };

                    if (CacheSize.HasValue)
                    {
                        queries.Add("PRAGMA cache_size=" + CacheSize.Value.ToString(CultureInfo.InvariantCulture));
                    }

                    if (EnableTempStoreMemory)
                    {
                        queries.Add("PRAGMA temp_store = memory");
                    }
                    else
                    {
                        queries.Add("PRAGMA temp_store = file");
                    }

                    db.ExecuteAll(string.Join(';', queries));
                }
                catch
                {
                    db.Dispose();
                    throw;
                }

                _dbConnection = db;
                _connection   = new ManagedConnection(db);
                return(_connection);
            }
        }
Ejemplo n.º 13
0
        internal DatabaseBackupImpl(sqlite3_backup backup, SQLiteDatabaseConnection srcDb, SQLiteDatabaseConnection destDb)
        {
            this.backup = backup;
            this.srcDb  = srcDb;
            this.destDb = destDb;

            this.dbDisposing       = (o, e) => Dispose();
            this.srcDb.Disposing  += dbDisposing;
            this.destDb.Disposing += dbDisposing;
        }
Ejemplo n.º 14
0
 public ManagedConnection(SQLiteDatabaseConnection db, bool closeOnDispose)
 {
     this.db         = db;
     _closeOnDispose = closeOnDispose;
 }
Ejemplo n.º 15
0
        protected DatabaseConnection CreateConnection(bool isReadOnly = false)
        {
            if (_connection != null)
            {
#if EMBY
                return(_connection.Clone(false));
#else
                return(_connection);
#endif
            }

            lock (WriteLock)
            {
                if (!_versionLogged)
                {
                    _versionLogged = true;
                }

                ConnectionFlags connectionFlags;

                if (isReadOnly)
                {
                    connectionFlags  = ConnectionFlags.Create;
                    connectionFlags |= ConnectionFlags.ReadWrite;
                }
                else
                {
                    connectionFlags  = ConnectionFlags.Create;
                    connectionFlags |= ConnectionFlags.ReadWrite;
                }

                if (EnableSingleConnection)
                {
                    connectionFlags |= ConnectionFlags.PrivateCache;
                }
                else
                {
                    connectionFlags |= ConnectionFlags.SharedCached;
                }

                connectionFlags |= ConnectionFlags.NoMutex;

#if EMBY
                var db = SQLite3.Open(DbFilePath, connectionFlags, null, false);
#else
                var db = SQLite3.Open(DbFilePath, connectionFlags, null);
#endif

                try
                {
                    if (string.IsNullOrWhiteSpace(_defaultWal))
                    {
                        var query = "PRAGMA journal_mode";
#if EMBY
                        using (var statement = PrepareStatement(db, query))
                        {
                            foreach (var row in statement.ExecuteQuery())
                            {
                                _defaultWal = row.GetString(0);
                                break;
                            }
                        }
#else
                        _defaultWal = db.Query(query).SelectScalarString().First();
#endif
                    }

                    var queries = new List <string>
                    {
                        "PRAGMA synchronous=Normal"
                    };

                    if (CacheSize.HasValue)
                    {
                        queries.Add("PRAGMA cache_size=" + CacheSize.Value.ToString(CultureInfo.InvariantCulture));
                    }

                    if (EnableTempStoreMemory)
                    {
                        queries.Add("PRAGMA temp_store = memory");
                    }
                    else
                    {
                        queries.Add("PRAGMA temp_store = file");
                    }

                    db.ExecuteAll(string.Join(";", queries.ToArray()));
                }
                catch
                {
                    db.Dispose();
                    throw;
                }

#if EMBY
                _connection = db;
                return(db);
#else
                _dbConnection = db;
                _connection   = new ManagedConnection(db);
                return(_connection);
#endif
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Get all changes fro SQLite Database
        /// </summary>
        /// <param name="schema">All Tables</param>
        /// <param name="lastModifiedDate">Changes since this date</param>
        /// <param name="uploadBatchSize">Maximum number of rows to upload</param>
        internal IEnumerable <SQLiteOfflineEntity> GetChanges(OfflineSchema schema, DateTime lastModifiedDate, int uploadBatchSize)
        {
            List <SQLiteOfflineEntity> lstChanges = new List <SQLiteOfflineEntity>();

            using (SQLiteDatabaseConnection connection = SQLitePCL.pretty.SQLite3.Open(localFilePath))
            {
                try
                {
                    foreach (var ty in schema.Collections)
                    {
                        // Get mapping from my type
                        var map = manager.GetMapping(ty);

                        // Create query to select changes
                        var querySelect = SQLiteConstants.SelectChanges;

                        var columnsDcl = new List <String>();
                        var columnsPK  = new List <String>();


                        // Foreach columns, create the tsql command to execute
                        foreach (var c in map.Columns)
                        {
                            if (!c.IsPK)
                            {
                                columnsDcl.Add("[s].[" + c.Name + "]");
                            }

                            // If it's the PK, add it from Tracking (because of deleted items not in real table
                            if (c.IsPK)
                            {
                                columnsDcl.Add("[t].[" + c.Name + "]");
                                columnsPK.Add("[s].[" + c.Name + "] = [t].[" + c.Name + "]");
                            }
                        }

                        var decl = string.Join(",\n", columnsDcl.ToArray());
                        var pk   = string.Join(" \nAND ", columnsPK.ToArray());
                        querySelect = String.Format(querySelect, map.TableName, pk, decl);

                        // add limit if specified
                        if (uploadBatchSize > 0)
                        {
                            querySelect += $" LIMIT {uploadBatchSize}";
                        }

                        try
                        {
                            // Get mapping form the statement
                            var  cols     = new TableMapping.Column[map.Columns.Length];
                            bool firstRow = true;

                            // While row is available
                            foreach (var row in connection.Query(querySelect, P(lastModifiedDate)))
                            {
                                if (firstRow)
                                {
                                    // Foreach column, get the property in my object
                                    for (int i = 0; i < cols.Length; i++)
                                    {
                                        var name = row[i].ColumnInfo.Name;
                                        var c    = map.FindColumn(name);
                                        if (c != null)
                                        {
                                            cols[i] = map.FindColumn(name);
                                        }
                                    }

                                    firstRow = false;
                                }

                                // Create the object
                                SQLiteOfflineEntity obj = (SQLiteOfflineEntity)Activator.CreateInstance(map.MappedType);

                                for (int i = 0; i < cols.Length; i++)
                                {
                                    if (cols[i] == null)
                                    {
                                        continue;
                                    }

                                    // Read the column
                                    var val = ReadCol(row, i, cols[i].ColumnType);

                                    // Set the value
                                    cols[i].SetValue(obj, val);
                                }

                                // Read the Oem Properties
                                var newIndex = map.Columns.Count();

                                obj.ServiceMetadata = new OfflineEntityMetadata();

                                obj.ServiceMetadata.IsTombstone = (bool)ReadCol(row, newIndex, typeof(Boolean));
                                obj.ServiceMetadata.Id          = (String)ReadCol(row, newIndex + 1, typeof(String));
                                obj.ServiceMetadata.ETag        = (String)ReadCol(row, newIndex + 2, typeof(String));
                                String absoluteUri = (String)ReadCol(row, newIndex + 3, typeof(String));
                                obj.ServiceMetadata.EditUri = String.IsNullOrEmpty(absoluteUri) ? null : new Uri(absoluteUri);

                                lstChanges.Add(obj);
                            }
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine(ex.Message);
                            throw;
                        }

                        // if we are batching uploads and the upload rowcount has been reached, skip
                        if (uploadBatchSize > 0 && lstChanges.Count >= uploadBatchSize)
                        {
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                    throw;
                }
            }

            // if we are batching uploads, limit the in-memory result set as well
            if (uploadBatchSize > 0)
            {
                return(lstChanges.Take(uploadBatchSize));
            }

            return(lstChanges);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Create a OfflineEntity Table with metadata information added
        /// </summary>
        internal void CreateTable(Type ty)
        {
            using (SQLiteDatabaseConnection connection = SQLitePCL.pretty.SQLite3.Open(localFilePath))
            {
                try
                {
                    // Get mapping from my type
                    var map = manager.GetMapping(ty);

                    // Create 2 tables : One for datas, one for tracking
                    var query         = SQLiteConstants.CreateTable;
                    var queryTracking = SQLiteConstants.CreateTrackingTable;

                    var columnsDcl         = new List <String>();
                    var columnsDclTracking = new List <String>();
                    var columnsPk          = new List <String>();

                    // Foreach columns, create the tsql command to execute
                    foreach (var c in map.Columns)
                    {
                        string dec = "\"" + c.Name + "\" " + Orm.SqlType(c) + " ";

                        columnsDcl.Add(dec);

                        // If it's the PK, add it to tracking
                        if (!c.IsPK)
                        {
                            continue;
                        }

                        columnsDclTracking.Add(dec);
                        columnsPk.Add(c.Name + " ");
                    }


                    var pkTracking = string.Join(",\n", columnsPk.ToArray());
                    // Adding metadatas to tracking table
                    columnsDclTracking.AddRange(GetOfflineEntityMetadataSQlDecl());

                    var decl         = string.Join(",\n", columnsDcl.ToArray());
                    var declTracking = string.Join(",\n", columnsDclTracking.ToArray());

                    string pKeyDecl = String.Empty;
                    if (columnsDclTracking.Count > 0)
                    {
                        pKeyDecl = String.Format(",\n PRIMARY KEY ({0})", pkTracking);
                    }

                    query         = String.Format(query, map.TableName, decl, pKeyDecl);
                    queryTracking = String.Format(queryTracking, map.TableName, declTracking, pKeyDecl);

                    connection.Execute(query);
                    connection.Execute(queryTracking);

                    var indexes = new Dictionary <string, IndexInfo>();
                    foreach (var c in map.Columns)
                    {
                        foreach (var i in c.Indices)
                        {
                            var       iname = i.Name ?? map.TableName + "_" + c.Name;
                            IndexInfo iinfo;
                            if (!indexes.TryGetValue(iname, out iinfo))
                            {
                                iinfo = new IndexInfo
                                {
                                    //IndexName = iname,
                                    TableName = map.TableName,
                                    Unique    = i.Unique,
                                    Columns   = new List <IndexedColumn>()
                                };
                                indexes.Add(iname, iinfo);
                            }

                            if (i.Unique != iinfo.Unique)
                            {
                                throw new Exception(
                                          "All the columns in an index must have the same value for their Unique property");
                            }

                            iinfo.Columns.Add(new IndexedColumn
                            {
                                Order      = i.Order,
                                ColumnName = c.Name
                            });
                        }
                    }

                    foreach (var indexName in indexes.Keys)
                    {
                        var          index     = indexes[indexName];
                        const string sqlFormat = "create {3} index if not exists \"{0}\" on \"{1}\"(\"{2}\")";
                        var          columns   = String.Join("\",\"",
                                                             index.Columns.OrderBy(i => i.Order).Select(i => i.ColumnName).ToArray());
                        var sql = String.Format(sqlFormat, indexName, index.TableName, columns,
                                                index.Unique ? "unique" : "");

                        connection.Execute(sql);
                    }

                    // Create Triggers
                    this.CreateTriggers(ty, connection);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                    throw;
                }
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Merg entities in SQLite DB
        /// </summary>
        internal void MergeEntities(Type ty, List <SQLiteOfflineEntity> entities)
        {
            using (SQLiteDatabaseConnection connection = SQLitePCL.pretty.SQLite3.Open(this.localFilePath))
            {
                // Get mapping from my type
                var map = manager.GetMapping(ty);

                // Foreach columns, create the list of columns to insert or update
                var columnsDcl            = new List <String>();
                var columnsValues         = new List <String>();
                var columnsDclTracking    = new List <String>();
                var columnsValuesTracking = new List <String>();

                foreach (var c in map.Columns)
                {
                    columnsDcl.Add("[" + c.Name + "]");
                    columnsValues.Add("? ");
                }
                foreach (var c in map.PrimaryKeys)
                {
                    columnsDclTracking.Add("\"" + c.Name + "\"");
                    columnsValuesTracking.Add("? ");
                }

                var decl               = string.Join(",", columnsDcl.ToArray());
                var declValues         = string.Join(",", columnsValues.ToArray());
                var declTracking       = string.Join(",", columnsDclTracking.ToArray());
                var declValuesTracking = string.Join(",", columnsValuesTracking.ToArray());

                var declValuePairs    = columnsDcl.Zip(columnsValues, (col, val) => col + "=" + val).ToArray();
                var declValuePairsStr = string.Join(",", declValuePairs);


                // Creating queries
                var queryInsert         = String.Format(SQLiteConstants.InsertOrIgnoreFromChanges, map.TableName, decl, declValues);
                var queryUpdate         = String.Format(SQLiteConstants.UpdateOrIgnoreFromChanges, map.TableName, declValuePairsStr, map.GetPrimaryKeysWhereClause);
                var queryUpdateTracking = String.Format(SQLiteConstants.InsertOrReplaceTrackingFromChanges, map.TableName, declTracking, declValuesTracking);
                var queryDelete         = String.Format(SQLiteConstants.DeleteFromChanges, map.TableName, map.GetPrimaryKeysWhereClause);
                var queryDeleteTracking = String.Format(SQLiteConstants.DeleteTrackingFromChanges, map.TableName, map.GetPrimaryKeysWhereClause);


                string pkeysNames = String.Join(", ", map.PrimaryKeys.Select(column => column.Name));
                var    querySelectItemPrimaryKeyFromTrackingChangesWithOemID =
                    String.Format(SQLiteConstants.SelectItemPrimaryKeyFromTrackingChangesWithOemID, map.TableName,
                                  pkeysNames);


                connection.RunInTransaction((conn) =>
                {
                    try
                    {
                        // Disable Trigger
                        this.DisableTriggers(map, conn);

                        foreach (var entity in entities)
                        {
                            // Foreach entity check if it's a delete action or un insert/update action
                            if (entity.ServiceMetadata.IsTombstone)
                            {
                                // Store values of primaryKeys
                                Object[] pkeys = new object[map.PrimaryKeys.Length];

                                // While row is available (only 1 if it's good)
                                foreach (var pkRow in conn.Query(querySelectItemPrimaryKeyFromTrackingChangesWithOemID, P(entity.ServiceMetadata.Id)))
                                {
                                    for (int i = 0; i < pkeys.Length; i++)
                                    {
                                        // Read the column
                                        pkeys[i] = ReadCol(pkRow, i, map.PrimaryKeys[i].ColumnType);
                                    }
                                }
                                // convert to valid parameters
                                pkeys = pkeys.Select(p => P(p)).ToArray();

                                // delete
                                conn.Execute(queryDelete, pkeys);
                                conn.Execute(queryDeleteTracking, pkeys);
                            }
                            else
                            {
                                // Get columns for insert
                                var cols = map.Columns;

                                // Set values for table
                                var insertParameters = new List <object>();
                                var updateParameters = new List <object>();
                                for (var i = 0; i < cols.Length; i++)
                                {
                                    var val = cols[i].GetValue(entity);
                                    //BindParameter(stmtInsert, i + 1, val);
                                    //BindParameter(stmtUpdate, i + 1, val);
                                    insertParameters.Add(val);
                                    updateParameters.Add(val);
                                }
                                // add where clause
                                for (var i = 0; i < map.PrimaryKeys.Length; i++)
                                {
                                    var val = map.PrimaryKeys[i].GetValue(entity);
                                    //BindParameter(stmtUpdate, cols.Length + i + 1, val);
                                    updateParameters.Add(val);
                                }
                                conn.Execute(queryUpdate, updateParameters.Select(p => P(p)).ToArray());
                                conn.Execute(queryInsert, insertParameters.Select(p => P(p)).ToArray());


                                // Set Values for tracking table
                                var trackingParameters = new List <object>();
                                trackingParameters.Add(entity.ServiceMetadata.IsTombstone);
                                trackingParameters.Add(0);
                                trackingParameters.Add(entity.ServiceMetadata.Id);
                                trackingParameters.Add("ETag");

                                var editUri = String.Empty;
                                if (entity.ServiceMetadata.EditUri != null &&
                                    entity.ServiceMetadata.EditUri.IsAbsoluteUri)
                                {
                                    editUri = entity.ServiceMetadata.EditUri.AbsoluteUri;
                                }

                                trackingParameters.Add(editUri);
                                trackingParameters.Add(DateTime.UtcNow);

                                // Set values for tracking table
                                for (var i = 0; i < map.PrimaryKeys.Length; i++)
                                {
                                    var val = map.PrimaryKeys[i].GetValue(entity);
                                    trackingParameters.Add(val);
                                }

                                conn.Execute(queryUpdateTracking, trackingParameters.Select(p => P(p)).ToArray());
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.Message);
                        throw;
                    }

                    // Re create Triggers
                    this.CreateTriggers(ty, conn);
                });
            }
        }
Ejemplo n.º 19
0
        bool runMigration(SQLiteDatabaseConnection db, string name)
        {
            var migration = Config.MigrationsProvider.GetMigration(name);

            var up   = new List <string>();
            var down = new List <string>();

            long id    = 0;
            var  state = 0;

            foreach (var line in migration.Split('\n'))
            {
                var id_match = Regex.Match(line, @"(?:--- database id )(\d+)");
                if (id_match.Success)
                {
                    id = long.Parse(id_match.Groups[1].Value);
                    continue;
                }

                if (Regex.IsMatch(line, @"--- database up"))
                {
                    state = 1;
                    continue;
                }

                if (Regex.IsMatch(line, @"--- database down"))
                {
                    state = 2;
                    continue;
                }

                var sql = line.Split(new char[] { '-', '-' })[0].Trim();

                switch (state)
                {
                case 1:
                    up.Add(sql);
                    break;

                case 2:
                    down.Add(sql);
                    break;
                }
            }

            if (id == 0)
            {
                throw new Exception("No id defined for the migration.");
            }

            var migration_sql = string.Join(" ", up).Trim();

            if (string.IsNullOrEmpty(migration_sql))
            {
                throw new Exception("Empty migration.");
            }

            var id_sql = string.Format("INSERT INTO __migrations ( id ) VALUES ( {0} )", id);

            return(db.TryRunInTransaction(
                       (t) =>
            {
                t.ExecuteAll(migration_sql);
                t.Execute(id_sql);
            }
                       ));
        }