예제 #1
0
        public void RemoveTask(RevaleeTask task)
        {
            if (task == null)
            {
                throw new ArgumentNullException("task");
            }

            if (_EseInstance == null)
            {
                throw new InvalidOperationException("Storage provider has not been opened.");
            }

            EseConnection connection = _ConnectionPool.OpenConnection();

            try
            {
                using (Table table = connection.GetTable(_TableNameCallbacks, OpenTableGrbit.Updatable))
                {
                    using (var transaction = new Transaction(connection))
                    {
                        Api.JetSetCurrentIndex(connection, table, null);
                        Api.MakeKey(connection, table, task.CallbackId, MakeKeyGrbit.NewKey);
                        if (Api.TrySeek(connection, table, SeekGrbit.SeekEQ))
                        {
                            Api.JetDelete(connection, table);
                            transaction.Commit(CommitTransactionGrbit.None);
                        }
                    }
                }
            }
            finally
            {
                _ConnectionPool.CloseConnection(connection);
            }
        }
예제 #2
0
        public RevaleeTask GetTask(Guid callbackId)
        {
            if (_EseInstance == null)
            {
                throw new InvalidOperationException("Storage provider has not been opened.");
            }

            EseConnection connection = _ConnectionPool.OpenConnection();

            try
            {
                using (Table table = connection.GetTable(_TableNameCallbacks, OpenTableGrbit.Updatable))
                {
                    IDictionary <string, JET_COLUMNID> columnIds = connection.GetSchema(_TableNameCallbacks);

                    Api.JetSetCurrentIndex(connection, table, null);
                    Api.MakeKey(connection, table, callbackId, MakeKeyGrbit.NewKey);
                    if (Api.TrySeek(connection, table, SeekGrbit.SeekEQ))
                    {
                        Guid?    storedCallbackId        = Api.RetrieveColumnAsGuid(connection, table, columnIds[_ColumnNameCallbackId]);
                        DateTime?createdTime             = Api.RetrieveColumnAsDateTime(connection, table, columnIds[_ColumnNameCreatedTime]);
                        DateTime?callbackTime            = Api.RetrieveColumnAsDateTime(connection, table, columnIds[_ColumnNameCallbackTime]);
                        string   callbackUrl             = Api.RetrieveColumnAsString(connection, table, columnIds[_ColumnNameCallbackUrl]);
                        int?     attemptsRemainingColumn = Api.RetrieveColumnAsInt32(connection, table, columnIds[_ColumnNameAttemptsRemaining]);
                        string   authorizationCipher     = Api.RetrieveColumnAsString(connection, table, columnIds[_ColumnNameAuthorizationCipher]);

                        Uri callbackUri = null;

                        if (callbackTime.HasValue &&
                            Uri.TryCreate(callbackUrl, UriKind.Absolute, out callbackUri) &&
                            createdTime.HasValue &&
                            storedCallbackId.HasValue &&
                            attemptsRemainingColumn.HasValue)
                        {
                            RevaleeTask revivedTask = RevaleeTask.Revive(
                                DateTime.SpecifyKind(callbackTime.Value, DateTimeKind.Utc),
                                callbackUri,
                                DateTime.SpecifyKind(createdTime.Value, DateTimeKind.Utc),
                                storedCallbackId.Value,
                                attemptsRemainingColumn.Value,
                                string.IsNullOrEmpty(authorizationCipher) ? null : authorizationCipher);

                            return(revivedTask);
                        }
                    }
                }

                return(null);
            }
            finally
            {
                _ConnectionPool.CloseConnection(connection);
            }
        }
예제 #3
0
            public void Dispose()
            {
                for (int connectionIndex = 0; connectionIndex <= this._HighWaterMark; connectionIndex++)
                {
                    EseConnection connection = this._ConnectionPool[connectionIndex];
                    if (connection != null)
                    {
                        this._ConnectionPool[connectionIndex] = null;
                        connection.Dispose();
                    }
                }

                GC.SuppressFinalize(this);
            }
예제 #4
0
        public void AddTask(RevaleeTask task)
        {
            if (task == null)
            {
                throw new ArgumentNullException("task");
            }

            if (_EseInstance == null)
            {
                throw new InvalidOperationException("Storage provider has not been opened.");
            }

            EseConnection connection = _ConnectionPool.OpenConnection();

            try
            {
                using (Table table = connection.GetTable(_TableNameCallbacks, OpenTableGrbit.Updatable))
                {
                    IDictionary <string, JET_COLUMNID> columnIds = connection.GetSchema(_TableNameCallbacks);

                    using (var transaction = new Transaction(connection))
                    {
                        using (var update = new Update(connection, table, JET_prep.Insert))
                        {
                            Api.SetColumn(connection, table, columnIds[_ColumnNameCallbackId], task.CallbackId);
                            Api.SetColumn(connection, table, columnIds[_ColumnNameCreatedTime], EnforceMinimumDateTime(task.CreatedTime));
                            Api.SetColumn(connection, table, columnIds[_ColumnNameCallbackTime], EnforceMinimumDateTime(task.CallbackTime));
                            Api.SetColumn(connection, table, columnIds[_ColumnNameCallbackUrl], task.CallbackUrl.OriginalString, Encoding.Unicode);
                            Api.SetColumn(connection, table, columnIds[_ColumnNameAttemptsRemaining], task.AttemptsRemaining);

                            if (task.AuthorizationCipher != null)
                            {
                                Api.SetColumn(connection, table, columnIds[_ColumnNameAuthorizationCipher], task.AuthorizationCipher, Encoding.Unicode);
                            }

                            update.Save();
                        }

                        transaction.Commit(CommitTransactionGrbit.None);
                    }
                }
            }
            finally
            {
                _ConnectionPool.CloseConnection(connection);
            }
        }
예제 #5
0
            public EseConnection OpenConnection()
            {
                lock (this._ConnectionLock)
                {
                    for (int connectionIndex = 0; connectionIndex <= this._HighWaterMark; connectionIndex++)
                    {
                        EseConnection connection = this._ConnectionPool[connectionIndex];

                        if (connection != null)
                        {
                            this._ConnectionPool[connectionIndex] = null;
                            return(connection);
                        }
                    }
                }

                return(new EseConnection(this._InstanceId, this._DatabasePath));
            }
예제 #6
0
            public void CloseConnection(EseConnection connection)
            {
                lock (this._ConnectionLock)
                {
                    for (int connectionIndex = 0; connectionIndex < this._PoolSize; connectionIndex++)
                    {
                        if (this._ConnectionPool[connectionIndex] == null)
                        {
                            this._ConnectionPool[connectionIndex] = connection;
                            if (connectionIndex > this._HighWaterMark)
                            {
                                this._HighWaterMark = connectionIndex;
                            }
                            return;
                        }
                    }
                }

                connection.Dispose();
            }
            public void CloseConnection(EseConnection connection)
            {
                lock (this._ConnectionLock)
                {
                    for (int connectionIndex = 0; connectionIndex < this._PoolSize; connectionIndex++)
                    {
                        if (this._ConnectionPool[connectionIndex] == null)
                        {
                            this._ConnectionPool[connectionIndex] = connection;
                            if (connectionIndex > this._HighWaterMark)
                            {
                                this._HighWaterMark = connectionIndex;
                            }
                            return;
                        }
                    }
                }

                connection.Dispose();
            }
        private void CreateTaskTable(EseConnection connection)
        {
            using (var transaction = new Transaction(connection))
            {
                JET_TABLEID tableId;
                Api.JetCreateTable(connection, connection.Database, _TableNameCallbacks, 16, 0, out tableId);
                try
                {
                    ColumndefGrbit notNullSetting = ColumndefGrbit.None;

                    if (EsentVersion.SupportsVistaFeatures || EsentVersion.SupportsWindows7Features)
                    {
                        notNullSetting = ColumndefGrbit.ColumnNotNULL;
                    }

                    var guidColumnDef = new JET_COLUMNDEF()
                    {
                        coltyp = JET_coltyp.Binary,
                        cbMax = 16,
                        grbit = ColumndefGrbit.ColumnFixed | notNullSetting
                    };

                    var datetimeColumnDef = new JET_COLUMNDEF()
                    {
                        coltyp = JET_coltyp.DateTime,
                        grbit = ColumndefGrbit.ColumnFixed | notNullSetting
                    };

                    var urlColumnDef = new JET_COLUMNDEF()
                    {
                        coltyp = JET_coltyp.LongText,
                        cbMax = 4096,
                        cp = JET_CP.Unicode,
                        grbit = notNullSetting
                    };

                    var integerColumnDef = new JET_COLUMNDEF()
                    {
                        coltyp = JET_coltyp.Long,
                        grbit = notNullSetting
                    };

                    var cipherColumnDef = new JET_COLUMNDEF()
                    {
                        coltyp = JET_coltyp.Text,
                        cbMax = 255,
                        cp = JET_CP.Unicode,
                        grbit = ColumndefGrbit.None
                    };

                    JET_COLUMNID columnId;

                    Api.JetAddColumn(connection, tableId, _ColumnNameCallbackId, guidColumnDef, null, 0, out columnId);
                    Api.JetAddColumn(connection, tableId, _ColumnNameCreatedTime, datetimeColumnDef, null, 0, out columnId);
                    Api.JetAddColumn(connection, tableId, _ColumnNameCallbackTime, datetimeColumnDef, null, 0, out columnId);
                    Api.JetAddColumn(connection, tableId, _ColumnNameCallbackUrl, urlColumnDef, null, 0, out columnId);
                    Api.JetAddColumn(connection, tableId, _ColumnNameAttemptsRemaining, integerColumnDef, null, 0, out columnId);
                    Api.JetAddColumn(connection, tableId, _ColumnNameAuthorizationCipher, cipherColumnDef, null, 0, out columnId);

                    string primaryIndexDef = string.Format(CultureInfo.InvariantCulture, "+{1}{0}{0}", Convert.ToChar(0), _ColumnNameCallbackId);
                    Api.JetCreateIndex(connection, tableId, "primary", CreateIndexGrbit.IndexPrimary, primaryIndexDef, primaryIndexDef.Length, 80);

                    string alternateIndexDef = string.Format(CultureInfo.InvariantCulture, "+{1}{0}+{2}{0}{0}", Convert.ToChar(0), _ColumnNameCallbackTime, _ColumnNameCreatedTime);
                    Api.JetCreateIndex(connection, tableId, "due", CreateIndexGrbit.IndexDisallowNull, alternateIndexDef, alternateIndexDef.Length, 80);
                }
                finally
                {
                    Api.JetCloseTable(connection, tableId);
                }

                transaction.Commit(CommitTransactionGrbit.None);
            }
        }
예제 #9
0
        private void CreateTaskTable(EseConnection connection)
        {
            using (var transaction = new Transaction(connection))
            {
                JET_TABLEID tableId;
                Api.JetCreateTable(connection, connection.Database, _TableNameCallbacks, 16, 0, out tableId);
                try
                {
                    ColumndefGrbit notNullSetting = ColumndefGrbit.None;

                    if (EsentVersion.SupportsVistaFeatures || EsentVersion.SupportsWindows7Features)
                    {
                        notNullSetting = ColumndefGrbit.ColumnNotNULL;
                    }

                    var guidColumnDef = new JET_COLUMNDEF()
                    {
                        coltyp = JET_coltyp.Binary,
                        cbMax  = 16,
                        grbit  = ColumndefGrbit.ColumnFixed | notNullSetting
                    };

                    var datetimeColumnDef = new JET_COLUMNDEF()
                    {
                        coltyp = JET_coltyp.DateTime,
                        grbit  = ColumndefGrbit.ColumnFixed | notNullSetting
                    };

                    var urlColumnDef = new JET_COLUMNDEF()
                    {
                        coltyp = JET_coltyp.LongText,
                        cbMax  = 4096,
                        cp     = JET_CP.Unicode,
                        grbit  = notNullSetting
                    };

                    var integerColumnDef = new JET_COLUMNDEF()
                    {
                        coltyp = JET_coltyp.Long,
                        grbit  = notNullSetting
                    };

                    var cipherColumnDef = new JET_COLUMNDEF()
                    {
                        coltyp = JET_coltyp.Text,
                        cbMax  = 255,
                        cp     = JET_CP.Unicode,
                        grbit  = ColumndefGrbit.None
                    };

                    JET_COLUMNID columnId;

                    Api.JetAddColumn(connection, tableId, _ColumnNameCallbackId, guidColumnDef, null, 0, out columnId);
                    Api.JetAddColumn(connection, tableId, _ColumnNameCreatedTime, datetimeColumnDef, null, 0, out columnId);
                    Api.JetAddColumn(connection, tableId, _ColumnNameCallbackTime, datetimeColumnDef, null, 0, out columnId);
                    Api.JetAddColumn(connection, tableId, _ColumnNameCallbackUrl, urlColumnDef, null, 0, out columnId);
                    Api.JetAddColumn(connection, tableId, _ColumnNameAttemptsRemaining, integerColumnDef, null, 0, out columnId);
                    Api.JetAddColumn(connection, tableId, _ColumnNameAuthorizationCipher, cipherColumnDef, null, 0, out columnId);

                    string primaryIndexDef = string.Format(CultureInfo.InvariantCulture, "+{1}{0}{0}", Convert.ToChar(0), _ColumnNameCallbackId);
                    Api.JetCreateIndex(connection, tableId, "primary", CreateIndexGrbit.IndexPrimary, primaryIndexDef, primaryIndexDef.Length, 80);

                    string alternateIndexDef = string.Format(CultureInfo.InvariantCulture, "+{1}{0}+{2}{0}{0}", Convert.ToChar(0), _ColumnNameCallbackTime, _ColumnNameCreatedTime);
                    Api.JetCreateIndex(connection, tableId, "due", CreateIndexGrbit.IndexDisallowNull, alternateIndexDef, alternateIndexDef.Length, 80);
                }
                finally
                {
                    Api.JetCloseTable(connection, tableId);
                }

                transaction.Commit(CommitTransactionGrbit.None);
            }
        }
예제 #10
0
        public IEnumerable <RevaleeTask> ListTasksDueBetween(DateTime startTime, DateTime endTime)
        {
            if (_EseInstance == null)
            {
                throw new InvalidOperationException("Storage provider has not been opened.");
            }

            DateTime rangeStartTime = EnforceMinimumDateTime(NormalizeDateTime(startTime));
            DateTime rangeEndTime   = EnforceMinimumDateTime(NormalizeDateTime(endTime));

            // Inclusive Upper Limit does not work properly for the CLR DateTime type.
            // Add the smallest amount of time that the Esent engine will detect to include the ending range inclusively.
            rangeEndTime = rangeEndTime.AddMilliseconds(1.0);

            EseConnection connection = this._ConnectionPool.OpenConnection();

            try
            {
                using (Table table = connection.GetTable(_TableNameCallbacks, OpenTableGrbit.DenyWrite | OpenTableGrbit.Preread | OpenTableGrbit.ReadOnly | OpenTableGrbit.Sequential))
                {
                    IDictionary <string, JET_COLUMNID> columnIds = connection.GetSchema(_TableNameCallbacks);
                    Api.JetSetCurrentIndex(connection, table, "due");
                    Api.MakeKey(connection, table, rangeStartTime, MakeKeyGrbit.NewKey);

                    if (Api.TrySeek(connection, table, SeekGrbit.SeekGE))
                    {
                        Api.MakeKey(connection, table, rangeEndTime, MakeKeyGrbit.NewKey);
                        if (Api.TrySetIndexRange(connection, table, SetIndexRangeGrbit.RangeInclusive | SetIndexRangeGrbit.RangeUpperLimit))
                        {
                            JET_SESID    jetSession                   = connection;
                            JET_TABLEID  jetTable                     = table;
                            JET_COLUMNID jetColumnCallbackId          = columnIds[_ColumnNameCallbackId];
                            JET_COLUMNID jetColumnCreatedTime         = columnIds[_ColumnNameCreatedTime];
                            JET_COLUMNID jetColumnCallbackTime        = columnIds[_ColumnNameCallbackTime];
                            JET_COLUMNID jetColumnCallbackUrl         = columnIds[_ColumnNameCallbackUrl];
                            JET_COLUMNID jetColumnAttemptsRemaining   = columnIds[_ColumnNameAttemptsRemaining];
                            JET_COLUMNID jetColumnAuthorizationCipher = columnIds[_ColumnNameAuthorizationCipher];

                            do
                            {
                                Guid?    callbackId              = Api.RetrieveColumnAsGuid(jetSession, jetTable, jetColumnCallbackId);
                                DateTime?createdTime             = Api.RetrieveColumnAsDateTime(jetSession, jetTable, jetColumnCreatedTime);
                                DateTime?callbackTime            = Api.RetrieveColumnAsDateTime(jetSession, jetTable, jetColumnCallbackTime);
                                string   callbackUrl             = Api.RetrieveColumnAsString(jetSession, jetTable, jetColumnCallbackUrl);
                                int?     attemptsRemainingColumn = Api.RetrieveColumnAsInt32(jetSession, jetTable, jetColumnAttemptsRemaining);
                                string   authorizationCipher     = Api.RetrieveColumnAsString(jetSession, jetTable, jetColumnAuthorizationCipher);

                                Uri callbackUri = null;

                                if (callbackTime.HasValue &&
                                    Uri.TryCreate(callbackUrl, UriKind.Absolute, out callbackUri) &&
                                    createdTime.HasValue &&
                                    callbackId.HasValue &&
                                    attemptsRemainingColumn.HasValue)
                                {
                                    RevaleeTask revivedTask = RevaleeTask.Revive(
                                        DateTime.SpecifyKind(callbackTime.Value, DateTimeKind.Utc),
                                        callbackUri,
                                        DateTime.SpecifyKind(createdTime.Value, DateTimeKind.Utc),
                                        callbackId.Value,
                                        attemptsRemainingColumn.Value,
                                        string.IsNullOrEmpty(authorizationCipher) ? null : authorizationCipher);

                                    yield return(revivedTask);
                                }
                            } while (Api.TryMoveNext(jetSession, jetTable));
                        }
                    }
                }
            }
            finally
            {
                _ConnectionPool.CloseConnection(connection);
            }

            yield break;
        }
예제 #11
0
        public IEnumerable <RevaleeTask> ListAllTasks()
        {
            if (_EseInstance == null)
            {
                throw new InvalidOperationException("Storage provider has not been opened.");
            }

            EseConnection connection = this._ConnectionPool.OpenConnection();

            try
            {
                using (Table table = connection.GetTable(_TableNameCallbacks, OpenTableGrbit.DenyWrite | OpenTableGrbit.Preread | OpenTableGrbit.ReadOnly | OpenTableGrbit.Sequential))
                {
                    IDictionary <string, JET_COLUMNID> columnIds = connection.GetSchema(_TableNameCallbacks);

                    if (Api.TryMoveFirst(connection, table))
                    {
                        JET_SESID    jetSession                   = connection;
                        JET_TABLEID  jetTable                     = table;
                        JET_COLUMNID jetColumnCallbackId          = columnIds[_ColumnNameCallbackId];
                        JET_COLUMNID jetColumnCreatedTime         = columnIds[_ColumnNameCreatedTime];
                        JET_COLUMNID jetColumnCallbackTime        = columnIds[_ColumnNameCallbackTime];
                        JET_COLUMNID jetColumnCallbackUrl         = columnIds[_ColumnNameCallbackUrl];
                        JET_COLUMNID jetColumnAttemptsRemaining   = columnIds[_ColumnNameAttemptsRemaining];
                        JET_COLUMNID jetColumnAuthorizationCipher = columnIds[_ColumnNameAuthorizationCipher];

                        do
                        {
                            Guid?    callbackId              = Api.RetrieveColumnAsGuid(jetSession, jetTable, jetColumnCallbackId);
                            DateTime?createdTime             = Api.RetrieveColumnAsDateTime(jetSession, jetTable, jetColumnCreatedTime);
                            DateTime?callbackTime            = Api.RetrieveColumnAsDateTime(jetSession, jetTable, jetColumnCallbackTime);
                            string   callbackUrl             = Api.RetrieveColumnAsString(jetSession, jetTable, jetColumnCallbackUrl);
                            int?     attemptsRemainingColumn = Api.RetrieveColumnAsInt32(jetSession, jetTable, jetColumnAttemptsRemaining);
                            string   authorizationCipher     = Api.RetrieveColumnAsString(jetSession, jetTable, jetColumnAuthorizationCipher);

                            Uri callbackUri = null;

                            if (callbackTime.HasValue &&
                                Uri.TryCreate(callbackUrl, UriKind.Absolute, out callbackUri) &&
                                createdTime.HasValue &&
                                callbackId.HasValue &&
                                attemptsRemainingColumn.HasValue)
                            {
                                RevaleeTask revivedTask = RevaleeTask.Revive(
                                    DateTime.SpecifyKind(callbackTime.Value, DateTimeKind.Utc),
                                    callbackUri,
                                    DateTime.SpecifyKind(createdTime.Value, DateTimeKind.Utc),
                                    callbackId.Value,
                                    attemptsRemainingColumn.Value,
                                    string.IsNullOrEmpty(authorizationCipher) ? null : authorizationCipher);

                                yield return(revivedTask);
                            }
                        } while (Api.TryMoveNext(jetSession, jetTable));
                    }
                }
            }
            finally
            {
                _ConnectionPool.CloseConnection(connection);
            }

            yield break;
        }
예제 #12
0
        public void Open(string connectionString)
        {
            if (_EseInstance == null)
            {
                if (string.IsNullOrWhiteSpace(connectionString))
                {
                    connectionString = ApplicationFolderHelper.ApplicationFolderName;
                }

                this._DatabasePath = Path.Combine(connectionString, Path.ChangeExtension(_DatabaseName, _StorageEngineBaseName));

                _EseInstance = new Instance(_DatabaseName);
                _EseInstance.Parameters.CreatePathIfNotExist = true;
                _EseInstance.Parameters.CircularLog          = true;
                _EseInstance.Parameters.Recovery             = true;
                _EseInstance.Parameters.BaseName             = _StorageEngineBaseName;
                _EseInstance.Parameters.MaxSessions          = _ConnectionPoolSize * 2;
                _EseInstance.Parameters.NoInformationEvent   = true;

                if (!string.IsNullOrEmpty(connectionString))
                {
                    _EseInstance.Parameters.SystemDirectory  = connectionString;
                    _EseInstance.Parameters.LogFileDirectory = connectionString;
                    _EseInstance.Parameters.TempDirectory    = connectionString;
                    _EseInstance.Parameters.AlternateDatabaseRecoveryDirectory = connectionString;
                }

                InitGrbit grbit = default(InitGrbit);
                if (EsentVersion.SupportsWindows7Features)
                {
                    grbit = Windows7Grbits.ReplayIgnoreLostLogs;
                }
                else
                {
                    grbit = InitGrbit.None;
                }

                _EseInstance.Init(grbit);
                _ConnectionPool = new EseConnectionPool(_EseInstance, _DatabasePath, _ConnectionPoolSize);

                EseConnection connection = _ConnectionPool.OpenConnection();

                try
                {
                    using (connection.GetTable(_TableNameCallbacks, OpenTableGrbit.ReadOnly))
                    {
                    }
                }
                catch (EsentErrorException eeex)
                {
                    if (eeex.Error == JET_err.ObjectNotFound)
                    {
                        CreateTaskTable(connection);
                    }
                    else
                    {
                        throw;
                    }
                }
                finally
                {
                    _ConnectionPool.CloseConnection(connection);
                }
            }
        }