internal void Execute(HyenaSqliteConnection hconnection, SqliteConnection connection)
        {
            if (finished)
            {
                throw new Exception("Command is already set to finished; result needs to be claimed before command can be rerun");
            }

            execution_exception = null;
            result = null;

            using (SqliteCommand sql_command = new SqliteCommand(CurrentSqlText)) {
                sql_command.Connection = connection;

                hconnection.OnExecuting(sql_command);

                try {
                    if (log_all)
                    {
                        ticks = System.Environment.TickCount;
                    }

                    switch (command_type)
                    {
                    case HyenaCommandType.Reader:
                        using (SqliteDataReader reader = sql_command.ExecuteReader()) {
                            result = new HyenaSqliteArrayDataReader(reader);
                        }
                        break;

                    case HyenaCommandType.Scalar:
                        result = sql_command.ExecuteScalar();
                        break;

                    case HyenaCommandType.Execute:
                    default:
                        sql_command.ExecuteNonQuery();
                        result = sql_command.LastInsertRowID();
                        break;
                    }

                    if (log_all)
                    {
                        Log.DebugFormat("Executed in {0}ms {1}", System.Environment.TickCount - ticks, sql_command.CommandText);
                        CommandExecutedHandler handler = CommandExecuted;
                        if (handler != null)
                        {
                            handler(this, new CommandExecutedArgs(Text, sql_command.CommandText, null, System.Environment.TickCount - ticks));
                        }
                    }
                } catch (Exception e) {
                    Log.DebugFormat(String.Format("Exception executing command: {0}", sql_command.CommandText), e.ToString());
                    execution_exception = e;
                }
            }

            finished_event.Reset();
            finished = true;
        }
        internal object WaitForResult(HyenaSqliteConnection conn)
        {
            while (!finished)
            {
                conn.ResultReadySignal.WaitOne();
            }

            object ret = result;

            // Reset to false in case run again
            finished = false;

            conn.ClaimResult();
            finished_event.Set();

            if (execution_exception != null)
            {
                throw execution_exception;
            }

            return(ret);
        }
        internal void Execute(HyenaSqliteConnection hconnection, Connection connection)
        {
            if (finished)
            {
                throw new Exception("Command is already set to finished; result needs to be claimed before command can be rerun");
            }

            execution_exception = null;
            result = null;
            int execution_ms = 0;

            string command_text = null;

            try {
                command_text = CurrentSqlText;
                ticks        = System.Environment.TickCount;

                switch (CommandType)
                {
                case HyenaCommandType.Reader:
                    using (var reader = connection.Query(command_text)) {
                        result = new ArrayDataReader(reader, command_text);
                    }
                    break;

                case HyenaCommandType.Scalar:
                    result = connection.Query <object> (command_text);
                    break;

                case HyenaCommandType.Execute:
                default:
                    connection.Execute(command_text);
                    result = connection.LastInsertRowId;
                    break;
                }

                execution_ms = System.Environment.TickCount - ticks;
                if (LogAll)
                {
                    Log.DebugFormat("Executed in {0}ms {1}", execution_ms, command_text);
                }
                else if (Log.Debugging && execution_ms > 500)
                {
                    Log.WarningFormat("Executed in {0}ms {1}", execution_ms, command_text);
                }
            } catch (Exception e) {
                Log.DebugFormat("Exception executing command: {0}", command_text ?? Text);
                Log.Exception(e);
                execution_exception = e;
            }

            // capture the text
            string raise_text = null;

            if (RaiseCommandExecuted && execution_ms >= RaiseCommandExecutedThresholdMs)
            {
                raise_text = Text;
            }

            finished_event.Reset();
            finished = true;

            if (RaiseCommandExecuted && execution_ms >= RaiseCommandExecutedThresholdMs)
            {
                var handler = CommandExecuted;
                if (handler != null)
                {
                    // Don't raise this on this thread; this thread is dedicated for use by the db connection
                    ThreadAssist.ProxyToMain(delegate {
                        handler(this, new CommandExecutedArgs(raise_text, execution_ms));
                    });
                }
            }
        }
 public SqliteModelProvider(HyenaSqliteConnection connection, string table_name) : this(connection, table_name, true)
 {
 }
 protected SqliteModelProvider(HyenaSqliteConnection connection)
 {
     Connection = connection;
 }
 public SqliteModelProvider(HyenaSqliteConnection connection, string table_name, bool checkTable) : this(connection)
 {
     this.table_name = table_name;
     check_table     = checkTable;
     Init();
 }
 public CacheableSqliteModelProvider(HyenaSqliteConnection connection, string table_name, bool check) : base(connection, table_name, check)
 {
 }
        public SqliteModelCache(HyenaSqliteConnection connection,
                                string uuid,
                                ICacheableDatabaseModel model,
                                SqliteModelProvider <T> provider)
            : base(model)
        {
            this.connection = connection;
            this.model      = model;
            this.provider   = provider;

            CheckCacheTable();

            if (model.SelectAggregates != null)
            {
                if (model.CachesJoinTableEntries)
                {
                    count_command = new HyenaSqliteCommand(String.Format(@"
                        SELECT count(*), {0} FROM {1}{2} j
                        WHERE j.{4} IN (SELECT ItemID FROM {3} WHERE ModelID = ?)
                        AND {5} = j.{6}",
                                                                         model.SelectAggregates, // eg sum(FileSize), sum(Duration)
                                                                         provider.TableName,     // eg CoreTracks
                                                                         model.JoinFragment,     // eg , CorePlaylistEntries
                                                                         CacheTableName,         // eg CoreCache
                                                                         model.JoinPrimaryKey,   // eg EntryID
                                                                         provider.PrimaryKey,    // eg CoreTracks.TrackID
                                                                         model.JoinColumn        // eg TrackID
                                                                         ));
                }
                else
                {
                    count_command = new HyenaSqliteCommand(String.Format(
                                                               "SELECT count(*), {0} FROM {1} WHERE {2} IN (SELECT ItemID FROM {3} WHERE ModelID = ?)",
                                                               model.SelectAggregates, provider.TableName, provider.PrimaryKey, CacheTableName
                                                               ));
                }
            }
            else
            {
                count_command = new HyenaSqliteCommand(String.Format(
                                                           "SELECT COUNT(*) FROM {0} WHERE ModelID = ?", CacheTableName
                                                           ));
            }

            uid = FindOrCreateCacheModelId(String.Format("{0}-{1}", uuid, typeof(T).Name));

            if (model.Selection != null)
            {
                selection_uid = FindOrCreateCacheModelId(String.Format("{0}-{1}-Selection", uuid, typeof(T).Name));
            }

            if (model.CachesJoinTableEntries)
            {
                select_str = String.Format(
                    @"SELECT {0} {10}, OrderID, {5}.ItemID  FROM {1}
                        INNER JOIN {2}
                            ON {3} = {2}.{4}
                        INNER JOIN {5}
                            ON {2}.{6} = {5}.ItemID {11}
                        WHERE
                            {5}.ModelID = {7} {8} {9}",
                    provider.Select, provider.From,
                    model.JoinTable, provider.PrimaryKey, model.JoinColumn,
                    CacheTableName, model.JoinPrimaryKey, uid,
                    String.IsNullOrEmpty(provider.Where) ? null : "AND",
                    provider.Where, "{0}", "{1}"
                    );

                reload_sql = String.Format(@"
                    DELETE FROM {0} WHERE ModelID = {1};
                        INSERT INTO {0} (ModelID, ItemID) SELECT {1}, {2} ",
                                           CacheTableName, uid, model.JoinPrimaryKey
                                           );
            }
            else if (model.CachesValues)
            {
                // The duplication of OrderID/ItemID in the select below is intentional!
                // The first is used construct the QueryFilterInfo value, the last internally
                // to this class
                select_str = String.Format(
                    @"SELECT OrderID, ItemID {2}, OrderID, ItemID FROM {0} {3} WHERE {0}.ModelID = {1}",
                    CacheTableName, uid, "{0}", "{1}"
                    );

                reload_sql = String.Format(@"
                    DELETE FROM {0} WHERE ModelID = {1};
                    INSERT INTO {0} (ModelID, ItemID) SELECT DISTINCT {1}, {2} ",
                                           CacheTableName, uid, provider.Select
                                           );
            }
            else
            {
                select_str = String.Format(
                    @"SELECT {0} {7}, OrderID, {2}.ItemID FROM {1}
                        INNER JOIN {2}
                            ON {3} = {2}.ItemID {8}
                        WHERE
                            {2}.ModelID = {4} {5} {6}",
                    provider.Select, provider.From, CacheTableName,
                    provider.PrimaryKey, uid,
                    String.IsNullOrEmpty(provider.Where) ? String.Empty : "AND",
                    provider.Where, "{0}", "{1}"
                    );

                reload_sql = String.Format(@"
                    DELETE FROM {0} WHERE ModelID = {1};
                        INSERT INTO {0} (ModelID, ItemID) SELECT {1}, {2} ",
                                           CacheTableName, uid, provider.PrimaryKey
                                           );
            }

            select_single_command = new HyenaSqliteCommand(
                String.Format(@"
                    SELECT OrderID FROM {0}
                        WHERE
                            ModelID = {1} AND
                            ItemID = ?",
                              CacheTableName, uid
                              )
                );

            select_range_command = new HyenaSqliteCommand(
                String.Format(String.Format("{0} {1}", select_str, "LIMIT ?, ?"), null, null)
                );

            select_first_command = new HyenaSqliteCommand(
                String.Format(
                    "SELECT OrderID FROM {0} WHERE ModelID = {1} LIMIT 1",
                    CacheTableName, uid
                    )
                );

            if (model.Selection != null)
            {
                delete_selection_command = new HyenaSqliteCommand(String.Format(
                                                                      "DELETE FROM {0} WHERE ModelID = {1}", CacheTableName, selection_uid
                                                                      ));

                save_selection_command = new HyenaSqliteCommand(String.Format(
                                                                    "INSERT INTO {0} (ModelID, ItemID) SELECT {1}, ItemID FROM {0} WHERE ModelID = {2} LIMIT ?, ?",
                                                                    CacheTableName, selection_uid, uid
                                                                    ));

                get_selection_command = new HyenaSqliteCommand(String.Format(
                                                                   "SELECT OrderID FROM {0} WHERE ModelID = {1} AND ItemID IN (SELECT ItemID FROM {0} WHERE ModelID = {2})",
                                                                   CacheTableName, uid, selection_uid
                                                                   ));
            }
        }