예제 #1
0
        public void Dispose()
        {
            // We need to end any pending transactions in the SqLite data access objects
            lock (_SQLiteFilesMgr_Lock)
            {
                if (_SQLiteFiles != null)
                {
                    for (int idx = _SQLiteFiles.Count - 1; idx >= 0; idx--)
                    {
                        SqLiteDAO nextDBLayer = _SQLiteFiles[idx];
                        lock (nextDBLayer.ClientCountWantingTransactionToStayOpen_Lock)
                        {
                            nextDBLayer.ClientCountWantingTransactionToStayOpen = 0;
                            nextDBLayer.CommitTransactionSession_ForcedCommit();
                            try
                            {
                                LogMessage(System.Diagnostics.TraceLevel.Verbose, "SqLite transactions commited and connection closed for: " + nextDBLayer.SqLiteDbPathAndFilename,
                                           MethodBase.GetCurrentMethod().DeclaringType.Name + "." + MethodBase.GetCurrentMethod().Name, Thread.CurrentThread.ManagedThreadId);
                            }
                            catch {}
                        }
                    }
                    _SQLiteFiles.Clear();
                }

                _DAO = null;
            }
        }
예제 #2
0
        public SqLiteMetadataManager(Boolean AutoCreateDB, UpdateLogCallBack iCallBackDelegate, SqLiteDAO dbAccess, List <TableMetadata> MetadataObjects)
        {
            _DBAccess                 = dbAccess;
            _MetadataObjects          = MetadataObjects;
            _DefaultUpdateLogCallback = iCallBackDelegate;

            InitOrCreateDatabase(AutoCreateDB);
            /*this.DBTableCreatedEvent += new OnDBTableCreated(DBMetadata_DBTableCreatedEvent);*/
        }
예제 #3
0
        public void Initialize(string dbFolder, string dbFilenameWithoutPath)
        {
            string methodNameForLogging = MethodBase.GetCurrentMethod().DeclaringType.Name + "." + MethodBase.GetCurrentMethod().Name;

            using (StopWatchProfiler profiler = new StopWatchProfiler("Init Enforcement Actions DB Access (Thread Task)", Logging.LogLevel.Debug, methodNameForLogging, System.Threading.Thread.CurrentThread.ManagedThreadId))
            {
                if (_IsInitialized == true)
                {
                    throw new Exception("OverstayVioActionDBManager singleton can only be initialized once");
                }

                _IsInitialized     = true;
                _FolderForDatabase = dbFolder;

                // We're supposed to recieve a filename without path information. But we'll go ahead and fixup if necessary
                if ((dbFilenameWithoutPath.Contains("\\")) || (dbFilenameWithoutPath.Contains("/")))
                {
                    dbFilenameWithoutPath = Path.GetFileName(dbFilenameWithoutPath);
                }
                string fullDBLogPathAndFilename = Path.Combine(_FolderForDatabase, dbFilenameWithoutPath);

                // We need to be thread-safe in this operation
                lock (_SQLiteFilesMgr_Lock)
                {
                    foreach (SqLiteDAO nextDBLayer in _SQLiteFiles)
                    {
                        // If we found an item with the same underlying filename, return it
                        if (string.Compare(nextDBLayer.SqLiteDbPathAndFilename, fullDBLogPathAndFilename, true) == 0)
                        {
                            _DAO = nextDBLayer;
                            break;
                        }
                    }

                    // If the desired layer doesn't exist in our list yet, create a new one and add it to the list
                    if (_DAO == null)
                    {
                        string dbConnectStr = string.Format("data source={0}", fullDBLogPathAndFilename);
                        _DAO = new SqLiteDAO(dbConnectStr, fullDBLogPathAndFilename, this.LogMessage);
                        _SQLiteFiles.Add(_DAO);
                    }
                }

                // Regardless of if we found an existing DB layer or created a new one, we will perform the DB Metadata check.
                // (This check will be very quick if it has already been validated, and will block until schema validation is finalized by any thread)
                // Note that this should be done outside of the "Lock" becasue we only want to lock out other threads when finding/modifying the
                // list of DB layers -- not when using them.
                // Before using the database, we need to be sure it has the correct Metadata/Schema information.
                // We will try to get exclusive access to a variable to see if whether or not the Metadata has been checked.
                // If we get exclusing access and DB Metadata hasn't been validated yet, we will do so now.
                if (!Monitor.TryEnter(_DAO.MetadataHasBeenChecked_Lock))
                {
                    // Somebody else already has this object locked. Let's immediately record this fact
                    Logging.AddTextToGenericLog(Logging.LogLevel.Debug, "SqLite Metadata check is already locked by another thread. (" + _DefaultDbFilenameWithoutPath + ")",
                                                System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name, System.Threading.Thread.CurrentThread.ManagedThreadId);

                    // Now we will do a normal Lock so we are blocked until the Metadata check is finished
                    lock (_DAO.MetadataHasBeenChecked_Lock)
                    {
                        Logging.AddTextToGenericLog(Logging.LogLevel.Debug, "Finished waiting for SqLite Metadata check to complete on different thread. (" + _DefaultDbFilenameWithoutPath + ")",
                                                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name, System.Threading.Thread.CurrentThread.ManagedThreadId);
                    }
                }
                else
                {
                    // The Monitor.TryEnter was successful, so we have a lock on the object. We will need to do Monitor.Exit when done
                    try
                    {
                        if (_DAO.MetadataHasBeenChecked == false)
                        {
                            Logging.AddTextToGenericLog(Logging.LogLevel.Debug, "Acquired exclusive access to verify SqLite Metadata. (" + _DefaultDbFilenameWithoutPath + ")",
                                                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name, System.Threading.Thread.CurrentThread.ManagedThreadId);

                            SqLiteMetadataManager _DBMetadata = new SqLiteMetadataManager(false, LogMessage, _DAO, _Metadata_OverstayVios.Tables);
                            _DBMetadata.CheckAllTables(true);
                            // Set flag so other threads know the Metadata check has already been performed
                            _DAO.MetadataHasBeenChecked = true;

                            // Update Metadata progress log in a thread-safe manner
                            Logging.AddTextToGenericLog(Logging.LogLevel.Debug, "Finished SqLite Metadata verification. (" + _DefaultDbFilenameWithoutPath + ")",
                                                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name, System.Threading.Thread.CurrentThread.ManagedThreadId);
                        }
                        else
                        {
                            Logging.AddTextToGenericLog(Logging.LogLevel.Debug, "No SqLite Metadata check needed -- it's already been performed. (" + _DefaultDbFilenameWithoutPath + ")",
                                                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name, System.Threading.Thread.CurrentThread.ManagedThreadId);
                        }
                    }
                    finally
                    {
                        // Set flag so other threads know the Metadata check has already been performed
                        _DAO.MetadataHasBeenChecked = true;

                        // Finally we will do the Monitor.Exit which does the unlocking
                        Monitor.Exit(_DAO.MetadataHasBeenChecked_Lock);
                    }
                }

                // Now we need to request DB transaction in the current DB access layer (This should never be done prior to the DB metadata being checked!)
                // Do a thread-safe increment of the counter to indicate transactions should stay active
                if (_DAO != null)
                {
                    lock (_DAO.ClientCountWantingTransactionToStayOpen_Lock)
                    {
                        if (_DAO.ClientCountWantingTransactionToStayOpen == 0)
                        {
                            _DAO.ClientCountWantingTransactionToStayOpen++;

                            // Start a DB session so things are a bit faster in this bulk operation...
                            // (The actual StartTransaction process will depend on how many "listeners" are wanting the transaction to stay active, and current state, etc.)
                            _DAO.StartTransactionSession();
                        }
                    }
                }
            }
        }