Siaqodb –cross platform database engine

We are very excited to announce today support for 3 extra platforms by our database engine: MonoTouch, MonoDroid and CompactFramework.

Siaqodb on MonoTouch

Since release of first version of Siaqodb we was interested to port on MonoTouch because of high community interests for this platform, but we postpone a bit because of some reasons, mainly because of limitations this platform has. Because Apple not allow JIT-ing on iOS, MonoTouch use AOT compilation and as consequence there are some important limitations that keep us away for some time.
Siaqodb usually “translates” a LINQ Expression tree into “internal language” so engine returns data queried in optimized way, but some LINQ queries cannot be optimized or it is needed to generate code at runtime based on LINQ Expression and in this case we call expression.Compile() and then apply that predicate(usually) over objects stored in DB. Main problem is that expression.Compile() generate code at runtime and this is not allowed by MonoTouch. Luckily we managed to optimize most of LINQ expression types and hopefully we can offer to developer workarounds by providing a equivalent LINQ query for the non-working one.
But in general we found that besides limitations, Siaqodb offer best API for a database on MonoTouch today, LINQ optimized queries, indexes, transactions…and performance is very close to native .NET app.
Here is a picture with Siaqodb running on iOS device:

siaqodb on iOS

siaqodb on iOS

And here is UI source code:

namespace SiaqodbMTDemo
{
	public class Application
	{
		static void Main (string[] args)
		{
			UIApplication.Main (args);
		}
	}

	// The name AppDelegate is referenced in the MainWindow.xib file.
	public partial class AppDelegate : UIApplicationDelegate
	{
		SharedBusinessLayer.PersonManager personManager;
		public override bool FinishedLaunching (UIApplication app, NSDictionary options)
		{
			window.MakeKeyAndVisible ();

			string dbPath= Environment.GetFolderPath (Environment.SpecialFolder.Personal);
			SharedBusinessLayer.SiaqodbFactory.SetDBName(dbPath);
                       personManager = new SharedBusinessLayer.PersonManager();

			button.TouchDown+=delegate {	PopulateDatabase(); };

			txtSearch.SearchButtonClicked+=delegate { this.Search(this.txtSearch.Text); };

			return true;
		}
		private void PopulateDatabase()
		{
			personManager.PopulateDatabase();
			IList<Person> persons = personManager.GetAllPersons();
                        this.tableView.Source = new TableViewDataSource(persons);
			this.tableView.ReloadData();
		}
		private void Search(string filterString)
		{
			var queryResult = personManager.GetPersonsFiltered(filterString);
			this.tableView.Source = new TableViewDataSource(queryResult.ToList());
			this.tableView.ReloadData();

		}

		private class TableViewDataSource : UITableViewSource
        {
            static NSString kCellIdentifier =new NSString ("MyIdentifier");
            private IList<Person> list;

            public TableViewDataSource (IList<Person> list)
            {
                this.list = list;

            }

            public override int RowsInSection (UITableView tableview, int section)
            {
				return list.Count;
            }

            public override UITableViewCell GetCell ( UITableView tableView, NSIndexPath indexPath)
            {
                UITableViewCell cell =tableView.DequeueReusableCell (kCellIdentifier);
                if (cell == null)
                {
                    cell = new UITableViewCell (UITableViewCellStyle.Default,kCellIdentifier);
                }
                cell.TextLabel.Text = list[indexPath.Row].ToString();
                return cell;
            }
        }
}

What is cool using Siaqodb is that you can share the Code between all platforms, in our examples projects we use SharedBusinessLayer assembly as shared assembly for all our examples:MonoTouch, MonoAndroid, Silverlight, WindowsPhone7 and CompactFramewok. Only difference is that we have a separate .csproj file that target each specific platform. So here is code of PersonManager class from SharedBusinessLayer assembly:

namespace SharedBusinessLayer
{
    public class PersonManager
    {
        Siaqodb siaqodb;
        string lastNames = @"CUNNINGHAM,BRADLEY,LANE,ANDREWS,RUIZ,HARPER,FOX,RILEY,ARMSTRONG,CARPENTER,WEAVER,GREENE,LAWRENCE,ELLIOTT,CHAVEZ,SIMS,AUSTIN,PETERS,KELLEY,FRANKLIN,LAWSON,FIELDS,GUTIERREZ,RYAN,SCHMIDT,CARR,VASQUEZ,CASTILLO,WHEELER,CHAPMAN,OLIVER,MONTGOMERY,RICHARDS,WILLIAMSON,JOHNSTON,BANKS,MEYER,BISHOP,MCCOY,HOWELL,ALVAREZ,MORRISON,HANSEN,FERNANDEZ,GARZA,HARVEY,LITTLE,BURTON,STANLEY,NGUYEN,GEORGE,JACOBS,REID,KIM,FULLER,LYNCH,DEAN,GILBERT,GARRETT,ROMERO,WELCH,LARSON,FRAZIER,BURKE,HANSON,DAY,MENDOZA,MORENO,BOWMAN,MEDINA,FOWLER,BREWER,HOFFMAN,CARLSON,SILVA,PEARSON,HOLLAND,DOUGLAS,FLEMING,JENSEN,VARGAS,BYRD,DAVIDSON,HOPKINS,MAY,TERRY,HERRERA,WADE,SOTO,WALTERS,CURTIS,NEAL,CALDWELL,LOWE,JENNINGS,BARNETT,GRAVES,JIMENEZ,HORTON,SHELTON";
        string firstNames = @"HAL,BRAIN,ROB,ELWOOD,KENDRICK,DARIUS,MOISES,SON,MARLIN,FIDEL,THADDEUS,CLIFF,MARCEL,ALI,JACKSON,RAPHAEL,BRYON,ARMAND,ALVARO,JEFFRY,DANE,JOESPH,THURMAN,NED,SAMMIE,RUSTY,MICHEL,MONTY,RORY,FABIAN,REGGIE,MASON,GRAHAM,KRIS,ISAIAH,VAUGHN,GUS,AVERY,LOYD,DIEGO,ALEXIS,ADOLPH,NORRIS,MILLARD,ROCCO,GONZALO,DERICK,RODRIGO,GERRY,STACEY,CARMEN,WILEY,RIGOBERTO,ALPHONSO,TY,SHELBY,RICKIE,NOE,VERN,BOBBIE,REED,JEFFERSON,ELVIS,BERNARDO,MAURICIO,HIRAM,DONOVAN,BASIL,RILEY,OLLIE,NICKOLAS,MAYNARD,SCOT,VINCE,QUINCY,EDDY,SEBASTIAN,FEDERICO,ULYSSES,HERIBERTO,DONNELL,COLE,DENNY,DAVIS,GAVIN,EMERY,WARD,ROMEO,JAYSON,DION,DANTE,CLEMENT,COY,ODELL,MAXWELL,JARVIS,BRUNO,ISSAC,MARY,DUDLEY";
        Random random = new Random();

        public PersonManager()
        {
            siaqodb = SiaqodbFactory.GetInstance();
        }

        public IList<Person> GetAllPersons()
        {
            return siaqodb.LoadAll<Person>();
        }

        public void PopulateDatabase()
        {
            string[] lastNamesArr = lastNames.Split(',');
            string[] firstNamesArr = firstNames.Split(',');
            for (int i = 0; i < 50; i++)
            {

                Person person = new Person();
                person.LastName = lastNamesArr[random.Next(100)];
                person.FirstName = firstNamesArr[random.Next(100)];
                person.Age = random.Next(18, 50);
                person.Married = (i % 2 == 0);

                siaqodb.StoreObject(person);

            }
            siaqodb.Flush();
        }
        public string filterString;
        public IEnumerable<Person> GetPersonsFiltered(string filter)
        {
            this.filterString = filter;

            var query = from Person pers in siaqodb
                        where pers.FirstName.Contains(filterString) || pers.LastName.Contains(filterString)
                        select pers;

            return query;
        }
        public void Save(Person person)
        {
            siaqodb.StoreObject(person);
        }
        public void Delete(Person person)
        {
            siaqodb.Delete(person);
            siaqodb.Flush();
        }
        public void Flush()
        {
            siaqodb.Flush();
        }
    }
}

About SyncFramework provider for MonoTouch version, we just want to let developers know that port is in progress and as soon SyncFramework 4.0 license allow using it in production, we will release also the SyncProvider.

About limitations… bellow we will try to give some examples that NOT work on MonoTouch but we can offer alternatives:
1.Use of a local method inside LINQ:

from Customer c in siaqodb
where c.NrEmployees==GetNrEmployees()
select c;

This query will crash when you will run on iOS device, but you can use a local variable that gets method returned value and then use this variable inside LINQ:

int  nrEmp= GetNrEmployees();
from Customer c in siaqodb
where c.NrEmployees==nrEmp
select c;

This will work fine.

2.call methods/properties of stored object members inside LINQ queries:

from Customer c in siaqodb
where c.Name.Length>10
select c;

Will crash on iOS device, siaqodb can only optimize following methods of members and only of string type members: StartsWith, EndsWith, Contains all the other methods of properties/members of stored objects call will result in a crash.

3.Unary !(not) operator use; following LINQ query:

from Customer c in siaqodb
where !c.Dismissed
select c;

Will crash, use instead equality operator like:

from Customer c in siaqodb
where c.Dismissed==false
select c;

This will work fine!

In general what is not allowed inside LINQ queries:
-methods call are not allowed, use instead a local variable and assign method returned value to it and then use that variable inside LINQ query wherever is possible
-methods call of object members other than StartsWith,EndsWith and Contains are not allowed.
-non comparison operators are not allowed, like:…where c.Age+4>30…use instead a local variable wherever is possible
-unary operators like !(not) are not allowed
-select(projection) should use only storable objects or object members, avoid any operations in select like: …select new {Name=c.Name+c.FirstName;}…
-multiple joins are not allowed, use instead 2 queries or appropriate workarounds to join results of 2 queries or so.

Important notice: those examples may work on iPhone/iPad Emulators but NOT work on devices.

About MonoDroid there is not many things changed since latest Beta, so see previous posts about it, about CompactFramework version we will detail more on a next post.
You can download latest versions for all platforms from our download page.

Happy “.NET everywhere”coding!

SiaqodbManager 2.0 released

Today we released SiaqodbManager 2.0,  before was WindowsForms based app and now we ported completely to WPF, see bellow the release notes:

  • Objects can be now Edited,Inserted and Deleted by SiaqodbManager without knowing runtime Type
  • It can open Silverlight, WP7 and Monodroid databases and run LINQ queries on them, so you can open a IsolatedStorage DB like a normal siaqodb .NET database and inspect objects saved
  • It supports now to open Encrypted databases after encryption settings are set.

See bellow a video demo of it:

We also released Siaqodb 2.5.2 version which get a lot of improvements:

  1. Extention methods optimization, following methods are optimized to read only needed data from database and not fetch from memory:
    • Any<T>(…)
    • Count<T>(…)
    • First<T>(…)
    • FirstOrDefault<T>(…)
    • Last<T>(…)
    • LastOrDefault(…)
    • Single<T>(…)
    • SingleOrDefault(…)
    • Take<T>(…)
    • Skip<T>(…)
  2. Most of them are very used , but Skip().Take() pair is most important for pagination. So for example:

    var query= (from Item it in siaqodb
    where it.ItemProperty > 10
    select it).Skip(20).Take(10);
    

    it will read and instantiate only necessary 10 objects

  3. methods StartsWith(..), Contains(..),EndsWith(..)  of strings members use now Index in case it exists
  4. 100% same format file for all platforms
  5. Move SetDatabaseFileName<T>(…) to SiaqodbConfigurator class.(old method still work but is marked as Obsolete)
  6. Other internal enhancements

Important notice is that upgrade can be made without any risk, new version is 100% compatible with older versions.

Siaqodb & Android & SyncFramework

A few days ago Novell make public the Preview of MonoDroid. “MonoDroid is a development stack for using C# and core .NET APIs
to develop Android-based applications.”  To run Siaqodb on MonoDroid is not enough like on Mono to just reference a .NET assembly, it requires like on Silverlight or MonoTouch that you compile your assembly on MonoDroid platform.We did not get any impediments on porting Siaqodb on Monodroid because Monodroid expose same API as Silverlight do and even more with less restrictions than Silverlight sandbox-> awesome work, MonoDroid team!!!

With almost no change (only UI) we port WP7 Siaqodb example to MonoDroid :

And the source code for sample above is:

namespace Siaqodb_MonoDroidDemo
{
    [Activity(Label = "Siaqodb on ANDROID", MainLauncher = true)]
    public class Activity1 : Activity
    {

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            SetContentView(Resource.layout.main);

            Button button = FindViewById<Button>(Resource.id.btnSearch);
            Button btnAdd= FindViewById<Button>(Resource.id.btnAdd);

            button.Click += new EventHandler(btnSearch_Click);
            btnAdd.Click += new EventHandler(btnAdd_Click);

            siaqodb = new Siaqodb(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal));

            PutSource();
        }
        public void PutSource()
        {
            IObjectList<Employee> employees = siaqodb.LoadAll<Employee>();

            ListView lst = FindViewById<ListView>(Resource.id.myList);
            lst.Adapter = new ArrayAdapter<Employee>(this, Resource.layout.list_item, employees);

        }
        void btnAdd_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 50; i++)
            {
                Employee employee = CreateRandomEmployee();
                siaqodb.StoreObject(employee);
            }
            siaqodb.Flush();
            //load from DB and put in listView
            PutSource();
        }
        string filterString;
        void btnSearch_Click(object sender, EventArgs e)
        {
            EditText txtInput = FindViewById<EditText>(Resource.id.entry);
            StringBuilder sb = new StringBuilder();
            foreach (char c in txtInput.Text)
            {
                sb.Append(c);
            }
            filterString = sb.ToString();

            var query = from Employee emp in siaqodb
                        where emp.FirstName.Contains(filterString) || emp.LastName.Contains(filterString)
                        select emp;

            IList<Employee> employees = new List<Employee>();
            foreach (Employee em in query)
            {
                employees.Add(em);
            }
            ListView lst = FindViewById<ListView>(Resource.id.myList);
            lst.Adapter = new ArrayAdapter<Employee>(this, Resource.layout.list_item, employees);

        }
}
}

What about Sync Framework?

Since SyncFramework 4.0 is designed to be used by any client platform in theory should not be a big problem to have a Siaqodb SyncProvider for MonoDroid. In practice we did not have any issue, we pickup WM6 CacheController example made by SyncFRW team port on MonoDroid, take Siaqodb SyncProvider for Silverlight and WP7 and compile on MonoDroid and voila:

So “Write once,run everywhere” became a reality about using Siaqodb as Client side database on many platforms.You can write your client Business Layer once using Siaqodb and use it for WPF,Silverlight,WindowsPhone7,Android and optionally Synchronize with SQLServer, again in same way everywhere.

To run samples above you need:

Before you run Siaqodb_MonoDroidSyncFRWDemo.sln be sure you read and followed steps described in previous post about using Siaqodb and SyncFramework, have installed SyncFx 4.0,read documentation, etc. Also same settings is available using MyGeneration to generate Offline Entities classes from SQLServer tables, into “\MyGenration template” folder you find the template.

Very important thing is that ListService service is installed on IIS and use it by the IP (like:http://192.168.1.100/ListService/DefaultScopeSyncService.svc/), it seems Android emulator not see “localhost” as local PC. To install ListService on IIS use steps described in “Microsoft Sync Framework 4.0 October CTP Documentation”  in section: “Tutorials and How To Procedures” -> “Optional:Deploying Service to IIS”.

If you have any question post it on our forum or put a comment on this post. As always for extra info you can ask  to our support: support(at) siaqodb(dot)com.

Siaqodb SyncFramework 4.0 provider

Last week Microsoft announced Sync Framework 4.0 October 2010 CTP that “extends the Sync Framework capabilities of building offline application to any client platform that is capable of caching data.”
For Siaqodb interesting platforms are Silverlight and WP7 and before above announcement, we collaborate closely with Microsoft to build up Siaqodb SyncFramework provider for Silverlight and WP7 and today we are happy to publish the BETA version -first Sync FRW 4.0 Provider on the market.
Go to download page to test it out (as pre-requirements download and install the SyncFrw 4.0 CTP )

How siaqodb can help Silverlight or WP7 apps? take a look at picture bellow:
SyncSyncFRW4

There are scenarios that users not have internet connection(especially when app is designed to be used in OOB mode), but still they need to use apps. Siaqodb provide client database for Silverlight and WP7 and now, with power of new Sync Framework 4.0, when user have back connection, user is able to Sync in background with a SQLServer database or another RDBMS.

First lets see technically how you as developer can use SiaqodbSync Provider.
If you are used with Siaqodb, there is known that main class that handle all database operations is Sqo.Siaqodb. To simplify things we made another class SiaqodbOffline that inherit from Sqo.Siaqodb so when you Insert/Update/Delete an object, if is used this derived class, is marked automatically with necessary flags so Sync provider knows what objects has to send to Server:

SiaqodbOffline siaqodbOffline = new SiaqodbOffline("myfirstdb", new Uri(@"http://localhost:49325/DefaultScopeSyncService.svc/"));

 siaqodbOffline.AddTypeForSync<Tag>();

 siaqodbOffline.Synchronize();

That’s all, we simplified a bit the way of SyncProvider would work, take a look on sample we did on download page.
Also for more info how to setup filter or other things consult documentation of SyncFramework 4.0.

As you will notice there was some Entities generated, for this we cannot use for now SyncSvcUtil.exe tool from Microsoft because it not yet allow customization (for future will do), so we used MyGeneration tool and we made a template, see readme.txt of installed folder how to use that template to generate the Entities.

Also as extra feature of Siaqodb 2.5 that need to be specified is Optimistic Concurrency that is very helpful in Sync scenario. Imagine user work on UI and change objects, but in background Sync is running and change objects also, in this case if Sync changed some objects and user changed too in UI, when user try to save his changes an OptimisticConcurrecny exception will be thrown.

Also Optimistic Concurrency feature can be used outside scope of Sync by adding in the class you want to have this feature a field:

ulong tickCount;

this is only condition needed; Siaqodb check automatically if object was changed by another thread and throw OptimisticConcurrecny exception.

Is known also that Microsoft provide possibility to cache data in collections and serialize those collection to IsolatedStorage, I want to point out some advantages Siaqodb has over Serialization of collections:
Advanatges of Siaqodb over IsolatedStorageOfflineContext:

-Cross platform embedded database solution: .NET (WPF, WindowsForms based apps), Silverlight, WP7, Mono , comming:MonoTouch and MonoDroid

-Use same SyncProvider ( same client code) for all platforms

-LINQ optimized provider

-Capable to read only Fields of stored objects without create object instances.

-support for Indexes on fields so fast loading data if Index involved.

-capable to deal with big amount of objects since is not in Memory collections, see performance: http://siaqodb.com/?p=258

-objects are not cached at all so GC may collect when is not used by app anymore, siaqodb “recognize” objects by OID(unique per Type)

-in OOB mode it can save objects to My… folders without change anything in code, just a param. It is more safety instead of IsolatedStorage store

-in Silverlight OOB mode performance is same as using .NET version(better then IsolatedStorage)

Features that Siaqodb has also like IsolatedStorageOfflineContext:

-automatic object schema refactoring
-thread safe
-Optimistic Concurrency support
-Encryption support(XTEA and AES implemented + plug-able Encryption algorithm)

Siaqodb 2.5 released

Siaqodb 2.5 was released today, main new features:

  • Transactions – ACID transactions are now part of Siaqodb, any object can be stored in transactional way.
  • Encryption – 2 built-in encryption algorithms(AES and XTEA) implemented but also can be used any (custom)encryption algorithm as a plugin.
  • Siaqodb is now SyncFramework 4.0 ready, on a next post we will explain and publish a BETA version of SiaqodbSyncProvider for SyncFramework 4.0
  • support for Nullable<> types
  • Details of features:

    Transactions
    ACID transactions are now fully supported – example of usage:

    Siaqodb siaqodb=new Siaqodb("dbPath");
    
    Transaction transact=siaqodb.BeginTransaction();
    
    invoiceDetail.Amount=400;
    
    invoiceTotal.Total += invoiceDetail.Amount;
    
    try
    {
         siaqodb.StoreObject(invoiceDetail,transact);
         siaqodb.StoreObject(invoiceTotal,transact);
    
         transact.Commit();
    }
    catch
    {
          transact.Rollback();
    }
    

    Encryption
    Data stored with Siaqodb can be now encrypted, by a built-in algorithm AES or XTEA. We implement both algorithms for 2 reasons: AES is widely adopted and most used and XTEA is one of the fastest encryption algorithms. You can choose one of them , by default AES with 128 bits blocksize algorithm is used.
    What you need to do enable encryption of your data: just one line of code

    SiaqodbConfigurator.EncryptedDatabase=true;
    

    you can choose between 2 built-in by:

    SiaqodbConfigurator.SetEncryptor(BuildInAlgorithm.XTEA);
    

    or you can use your own implementation of an encryption algorithm by implementing IEncryptor interface and then set the algorithm like:

    class MyEncryptor: IEncryptor
    {
      .....
    }
    SiaqodbConfigurator.SetEncryptor(new MyEncryptor());
    

    you can also set a password for encryption algorithm by:

    SiaqodbConfigurator.SetEncryptionPassword("mypwd");
    

    Important to notice:
    1.Set all encryption settings before open any database
    2.Once you use encryption you cannot use another algorithm(switch them) for same database, data will not be possible to decrypt anymore.
    3.Once you set a password , you need to open the DB with same pwd, in other words you cannot just change pwd, if your scenario really need to change encryption algorithm, then you need to backup DB in memory or XML with old pwd, set new pwd and then save it back, similar procedure should be applied if is changed encryption algorithm.

    So as conclusion to encrypt data stored on Siaqodb you need just one line of code:

    SiaqodbConfigurator.EncryptedDatabase=true;
    

    the rest of settings are optional.

    support for Nullable<> types
    Now Siaqodb is able to store objects that has members as Nullable<> type :

    public class MyType
    {
        public Nullable<int> myInt;
        public int? myInt2;
    }
    

    Siaqodb 2.0 released

    We are excited to announce that Siaqodb 2.0 was released today. The main features added are:

    • POCO support- now a storable class is not mandatory anymore to implement ISqoDataObject or to inherit from SqoDataObject
    • Indexes support added – now you can index by a property/field so queries are much faster if index is involved.
    • Attributes like Index, UniqueConstraint, MaxLength, Ignore can be used also on automatic properties
    • Added new methods on Siaqodb class like:DeleteObjectBy(…) or LoadObjectByOID(…)
    • Support for just released WP7 developer tools BETA

    Let’s detail a bit about those features added and reasons…

    POCO support:

    Since start-up of project many developers found that inheriting from base class or even implement only the ISqoDataObject interface is a limitation of Siaqodb and main reason is most of the time from Architectural point of view. There are many pro/cons about POCO, here is an example, also EF4 support now POCO after feedback from developers and interesting feedback was given  here
    and seems MS really took in consideration since EF4 support it, take a look at new Scott Guthrie’s blog post

    Is out of scope to detail more about pro/cons of POCO and in above links you can find very interesting arguments, important thing is that Siaqodb provide freedom to developer to use POCO or not.

    So as an example following Type can be stored on Siaqodb:

    public class MyPOCO
    {
           public int OID { get; set; }
           public int MyInt{ get; set; }
           public string MyStr { get; set; }
           public Guid UId{ get; set; }
    }
    

    There is still a requirement for a storable class: every storable classe should define OID property, and on Silverlight is needed to declare 2 extra methods because of Silverlight reflection limitation, so on Silverlight POCO class definition would look like:

    public class MyPOCO
    {
           public int OID { get; set; }
           public int MyInt{ get; set; }
           public string MyStr { get; set; }
           public Guid UId{ get; set; }
           public object GetValue(System.Reflection.FieldInfo field)
            {
                return field.GetValue(this);
            }
            public void SetValue(System.Reflection.FieldInfo field, object value)
            {
                field.SetValue(this, value);
            }
    
    }
    

    But what about attributes like Ignore,UniqueConstraint, etc? if I decorate properties of my entities with those attributes then we violate POCO definition. Solution is to use SiaqodbConfigurator, so for example if you want to add an Index instead of putting
    an Attribute Index on property you add index by SiaqodbConfigurator method like:

    SiaqodbConfigurator.AddIndex("UId", typeof(MyPOCO));
    SiaqodbConfigurator.AddUniqueConstraint("UId", typeof(MyPOCO));
    
     Siaqodb sq = new Siaqodb(objPath);
     Guid id=Guid.NewGuid();
     sq.StoreObject(new MyPOCO(){MyInt=3,UId=id});
    
     var q = from MyPOCO myobj in siaqodb
                 where myobj.UId == id //index is used->fast query
                 select myobj;
    

    INDEX support

    Indexes are implemented using AVL trees ;
    adding an index to a field will speed up your queries that involve that field, example:

     class ClassWithIndex
        {
            public int OID { get; set; }
    
            [Index]
            public int MyID { get; set; }
    
            public string Name { get; set; }
        }
    
    .....
    
                Siaqodb siaqodb = new Siaqodb(Program.siaoqodbPath);
                siaqodb.DropType<ClassWithIndex>();
    
                for (int i = 0; i < 100000; i++)
                {
                    ClassWithIndex myobj = new ClassWithIndex() ;
                    myobj.MyID=i%10;
                    myobj.Name = "MyTest" + i.ToString() ;
    
                    siaqodb.StoreObject(myobj);
                }
                DateTime start = DateTime.Now;
                var q = from ClassWithIndex myobj in siaqodb
                          where myobj.MyID == 8 //here will be used index lookup
                          select myobj;
                int k = 0;
                foreach (ClassWithIndex obj in q)
                {
                    //do something with object
                    k++;
                }
                string timeElapsed = (DateTime.Now - start).ToString();
    
                Console.WriteLine("Time elapsed to load:" + k.ToString() + "objects from 100.000 stored objects  filtered by index:" + timeElapsed);
    

    Index are also useful and is really recommended if is used a UniqueConstraint to a field then use also Index to that field, because on Insert/Update lookup for uniqueness, index will be used so faster insert/update.

    Support for just released WP7 dev. tools BETA

    Just a few days ago Microsoft released Windows Phone Developer Tools Beta
    There are some big changes and Siaqodb now fully support WP7 Beta, example is also compiled under BETA and not anymore on CTP version of WP7 dev. tools.

    Important for existing users: upgrade can be made on the fly, Siaqodb 2.0 is fully compatible with older versions.

    So to see Siaqodb 2.0 in action, download latest setup and run Examples.

    siaqodb performance

    Anytime when a user looks for a new solution (especially for a database) first time is curious about performance. We will try to provide a quick overview about performance of siaqodb on  .NET platform.
    Let’s define first a Class to manipulate it:

    public class Employee : ISqoDataObject
    {
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime HireDate { get; set; }
    public int Age { get; set; }
    private int oid;
    public int OID
    {
    get { return oid; }
    set { oid = value; }
    }
    }
    

    Then make a method to Create an Employee object:

    private Employee CreateRandomEmployee()
    {
    string[] lastNamesArr = lastNames.Split(',');
    string[] firstNamesArr = firstNames.Split(',');
    Employee employee = new Employee();
    employee.LastName = lastNamesArr[random.Next(100)];
    employee.FirstName = firstNamesArr[random.Next(100)];
    employee.Age = random.Next(18, 50);
    employee.HireDate = new DateTime(random.Next(1995, 2010), random.Next(1, 12), random.Next(1, 28));
    
    return employee;
    }
    

    Let’s take on .NET platform and handle 10.000 and 100.000 objects:
    a. INSERT

    Siaqodb siaqodb=new Siaqodb(@"C:\MyObjects");
    DateTime start=DateTime.Now;
    for(int i=0;i<10000;i++)
    {
    Employee emp=CreateRandoEmployee();
    
    siaqodb.StoreObject(emp);
    }
    string timeElapsed=(DateTime.Now-start).ToString();
    

    for 10.000 objects ->timeElapsed=0.60 seconds

    for 100.000 objects ->timeElapsed=5.93 seconds

    b.READ

    • Read all objects:
    • start=DateTime.Now;
      IObjectList<Employee> list=siaqodb.LoadAll<Employee>();
      string timeElapsed=(DateTime.Now-start).ToString();
      

      for 10.000 ->timeElapsed=0.20 seconds

      for 100.000 ->timeElapsed=2.14 seconds

    • Search for Employees with Age>30
    • start=DateTime.Now;
      
      var q=from Employee emp in siaqodb
      where emp.Age>30
      select emp;
      
      int nrEmp=0;
      
      foreach(Employee e in q)
      {
      //do something with employee
      nrEmp++;
      }
      string timeElapsed=(DateTime.Now-start).ToString();
      

      for 10.000 ->nrEmp=5933 and timeElapsed=0.18 seconds

      for 100.000 ->nrEmp=59493 and timeElapsed=1.64 seconds

    • Search for Employees with Age>30 and that  FirstName contains ‘J’ character
    • start=DateTime.Now;
      
      var q=from Employee emp in siaqodb
      where emp.Age>30 && emp.FirstName.Contains("J");
      select emp;
      
      int nrEmp=0;
      
      foreach(Employee e in q)
      {
      //do something with employee
      nrEmp++;
      }
      string timeElapsed=(DateTime.Now-start).ToString();
      

      for 10.000 ->nrEmp=359 and timeElapsed=0.19 seconds

      for 100.000 ->nrEmp=3512 and timeElapsed=2.04 seconds

    c.UPDATE

    
    IObjectList<Employee> list=siaqodb.LoadAll<Employee>();
    start=DateTime.Now;
    foreach(Employee emp in list)
    {
    emp.Age=emp.Age % 30;
    //update occur
    siaqodb.StoreObject(emp);
    }
    string timeElapsed=(DateTime.Now-start).ToString();
    

    for 10.000 ->timeElapsed=0.21 seconds

    for 100.000 ->timeElapsed=2.08 seconds


    d.DELETE

    IObjectList<Employee> list=siaqodb.LoadAll<Employee>();
    start=DateTime.Now;
    foreach(Employee emp in list)
    {
    
    siaqodb.Delete(emp);
    }
    string timeElapsed=(DateTime.Now-start).ToString();
    

    for 10.000->timeElapsed=0.10 seconds

    for 100.000->timeElapsed=1.06 seconds

    Tests was done on a machine with processor Core 2 Duo 2.2 GHz , 4GB RAM, HDD Samsung 7400 r/min, Windows 7 OS

    siaqodb and ASP.NET 4.0

    We just released Siaqodb 1.1 and the big change is that a Type of which objects are storable not need anymore(mandatory) to inherit from base class SqoDataObject, it only need to implement ISqoDataObject interface. Also as consequence SqoDataObject class has public setter for OID.

    What these changes bring beside flexibility of client code?

    Well… is known that on Web Based app (and we speak here about ASP.NET) object are created on server side and sent to client; when user do a POST or GET HTTP request objects can be created back, but until now because a Siaqodb storable object are identified by its OID and OID not had public setter, using an ObjectDataSource component and putting as DataObjectType a Siaqodb storable Type not works because when HTTP POST request occur to Save an existing object,  it fails because ObjectDataSource could not set back OID for the object.

    Now with just a few lines of code and with power of ASP.NET Dynamic Data and Siaqodb you can make a data-driven app faster than ever. A demo of this can be found in the Siaqodb setup .

    Ofcourse Siaqodb is embedded database engine means database is embedded into your ASP.NET app and available only for that app. But you can copy anytime and inspect via SiaqodbManager. What you only need to take care is to have read/write access into App_Data folder of your project, nothing else needed to be  installed or configured, just reference siaqodb.dll assembly.

    Siaqodb is thread-safe means your website can be accessed concurrently by any numbers of users, you dont have any risks. We tested with automated tools and website behave very good, fast, stable at high number of concurrent users.

    Expression.Compile() on WindowsPhone 7

    An interesting thing on WindowsPhone 7 platform is that sometimes a LambdaExpression can be compiled and sometimes not; how come? we was confused too and reason is that Reflection.Emit is not supported on WindowsPhone7 and Expression.Compile() sometimes use Reflection.Emit and sometimes not, depends of your expression so sometimes works and sometimes not.
    [Edited]Compile() method of an expression was available in Preview release of WP7 SDK, in the RTM, MS removed Compile () method completely [/Edited]
    Problem was confirmed by Microsoft : http://social.msdn.microsoft.com/Forums/en/windowsphone7series/thread/4469af62-66ca-44b0-a256-1bdd228b2539 and let’s hope will be found a solution by them in future but till then what we can do? because Siaqodb use this method for LINQ queries and ofcourse “sometimes” not work (some LINQ queries).

    So we download latest stable sources of Mono 2.6.4 and try a hack maybe it is a way to compile a LambdaExpression from MS System.Core with Mono Expression compiler.

    And yeah we managed to Compile a MS System.Core LambdaExpression with Mono Expression compiler implementation, NOT using Reflection.Emit with just small changes of Mono sources. We made an assembly: ExpressionCompiler.dll (has only 36KB) and developer can do: ExpressionCompiler.Compile(LambdaExpression expression); instead of default: expression.Compile(). Of course all sources we published and can be downloaded for free (according with MIT license), also ExpressionCompiler assembly can be used in any project(not only with Siaqodb).

    Sources are included in new Siaqodb trial setup.
    One thing to notice : Mono expression compiler use Reflection to access for example a private field you use in a expression , so since Silverlight not support Reflection on private members(only from class itself you can access by reflection) means you need to make your field/fields, used in expression, public.

    Shout it kick it on DotNetKicks.com

    Siaqodb on WindowsPhone 7

    [Edited 19 July 2010]
    Example is now build with Siaqodb 2.0 for latest WindowsPhone7 BETA release
    [End Edit]
    A few days ago Microsoft launched Development Platform for WindowsPhone 7. Development can be done on 2 main Frameworks:
    -Silverlight
    -XNA Framework
    Main interest for Siaqodb is Silverlight ofcourse and I start reading to see what version of Silverlight and if support LINQ etc. So what I find first thing that make me said Siaqodb will not gonna work is: “LINQ query providers for custom data sources are not supported in Silverlight for Windows Phone.” Damn…I was thinking is because on .NET Compact Framework that is not supported too, and especially because System.Linq.Expressions namespace is not supported. But further reading surprise: System.Linq.Expressions I don’t see in unsupported list, but I see that IQueryable, Queryable and IQueryProvider not supported. Since nothing about Expressions namespace is said and since Siaqodb use to make LINQ provider redefining technique of Where, Join, Select extension methods of IEnumerable, I start download all developer tools for WindowsPhone and after installation and running and with small adjustments , voila:SiaqodbWP7

    Some things to notice about Silverlight on Windows Phone 7 platform:

    -Isolated storage on Windows Phone does not enforce quotas to restrict the size of isolated storage for Silverlight-based applications. The default quota size of 1 MB does not apply. (source MSDN)

    -SiaqodbSilver.dll  can be used/shared by both types of Applications Silverlight based(in browser or out of browser) and Silverlight for Windows Phone 7

    Happy storing data! :)