Problem with Purge and application restart (72740)

Feb 3, 2011 at 11:58 AM

Hi,

unfortunately I have discovered a strange behaviour in the current version of Sterling DB.
In some case I need my application to delete all entries from a table and than to fill it again. The procedure is
1) Purge
2) Save (a lot of items)

Everything works fine as long as the application is running.
But when I restart the application, Sterling tells me that the database is empty (no keys).

I guess, that has something to do with Purge() deleting the "tables.dat" file. On the next startup Sterling is not able to find the table definition for my items and creates a new table directory.

The problem was not there in version 0.9.

It is not easy to reproduce this problem in unit tests, because of the static SterlingFactory which creates an instance of PathProvider
(which contains _databaseMaster and _tableMaster). _databaseMaster and _tableMaster are not affected when the engine is disposed and recreated.

To simulate an application restart I have modified the SterlingFactory:

        static SterlingFactory()
        {
            _Initialize();
        }

        internal static void _Initialize()
        {
            _logManager = new LogManager();
            _pathProvider = new PathProvider(_logManager);
            _database = new SterlingDatabase(_logManager);         
        }

And than I was able to reproduce the problem in an additional test in Wintellect.Sterling.Test.Database.TestPurge

       [TestMethod]
       public void TestSaveAfterPurge()
       {
           SimulateNextApplicationStart();

           // Clear the database and refill with values.
           _databaseInstance.Purge();
           _databaseInstance.Save(TestModel.MakeTestModel());
           _databaseInstance.Save(TestModel.MakeTestModel());
           Assert.IsTrue(_databaseInstance.Query<TestModel, int>().Any(), "Save after purge failed: key list is empty.");

           SimulateNextApplicationStart();

           // This assert will fail !
           Assert.IsTrue(_databaseInstance.Query<TestModel, int>().Any(), "Query after restart failed: key list is empty.");
       }

       private void SimulateNextApplicationStart()
       {
           _engine.Dispose();

           SterlingFactory._Initialize();
           _engine = new SterlingEngine();
           _engine.Activate();
           _databaseInstance = _engine.SterlingDatabase.RegisterDatabase<TestDatabaseInstance>();
       }

Best regards,
kallocain
Coordinator
Feb 3, 2011 at 6:52 PM

I was able to duplicate the problem in my unit test. I'll take a look and find out what's going on. Thanks!

Coordinator
Feb 3, 2011 at 7:27 PM

Thanks for identifying this. I believe it has been fixed. Can you please grab the latest source and then confirm here whether it addresses your issue? Thanks!

Feb 4, 2011 at 7:08 AM

Thank you very much for your fast response. If have tried version 72798 - and it works fine, as long as the database is shut down correctly.

I don´t want to seem ungrateful - but I am working on a healthcare application where in some cases ten thousand of items are downloaded and stored locally (patient data, disease catalogs, product catalogs etc.). The application is than running for hours and hours - probably not shut down for several days. When something bad is going to happen (browser crash, nurse pulling power cord etc.) the data will be lost on next startup, because the application was not able to call SterlingDatabase.Deactivate().

As a quick (and very ugly) workaround I have modified BaseDatabaseInstance.Purge() to call _pathProvider.Serialize() after the database has been deleted.

 

Best regards,
kallocain