Siaqodb v3.0 released

We happy to announce that we just released version 3.0 of Siaqodb.
There are not many extra things since our BETA release so for details of features see previous blog post.

We also released SiaqodbManager 3.0 (which was not in our BETA) that fully support database created with version 3.0, the nested objects or Lists/Arrays of nested objects may be opened by clicking on the cell, see screenshot bellow:
SiaqodbManager3.0

Finally, we released also Siaqodb Sync Framework Provider which is based on Microsoft Sync Framework Toolkit .

Siaqodb Sync Framework Provider is available for all platforms: .NET, Silverlight,WindowsPhone7, MonoAndroid, MonoTouch, CompactFramework.
There are many cool things to be said about this release so we will dedicate separate posts about it in near future.

Stay tuned and enjoy the new version!

Siaqodb and nested objects

We are excited to announce Siaqodb 3.0 Beta version ready for download. It is a major version and will be available for all platforms: .NET, Silverlight, WindowsPhone7, Mono, MonoTouch, MonoAndroid and Unity3D. The main feature we introduce in this version (the most requested by developers) is support for nested objects and Lists/Arrays of complex objects, Siaqodb being able now to store full graph of object no matter how complex it is.

Example of  a storable object/s :

public class Order
    {
        public int OID { get; set; }
        public Customer OrderCustomer { get; set; }
        public List<OrderDetail> Details{get;set;}
        public DateTime OrderDate { get; set; }
        public int OrderNumber { get; set; }
    }
    public class OrderDetail
    {
        public int OID { get; set; }
        public Product DetailProduct { get; set; }
        public decimal Price { get; set; }
        public decimal Quantity { get; set; }
    }
    public class Product
    {
        public int OID { get; set; }
        public string Name { get; set; }
    }
    public class Customer
    {
        public int OID { get; set; }
        public string Name { get; set; }
        public Address Address { get; set; }
       
    }
    public class Address
    {
        public int OID { get; set; }
        public string Street { get; set; }
        public string City { get; set; }
    }

And now query the db:

 var query = from Order o in siaqodb
                     where o.OrderCustomer.Name == "CustomerX"
                     select o;

Above query runs optimized, only objects that match with criteria will be loaded/created from database.
Also very important, in queries you can compare complex objects like:

            Customer customer = new Customer() { Name = "CustomerX", Address = new Address() { City = "Berlin" } };

            var q = from Order o in siaqodb
                    where o.OrderCustomer == customer
                    select o;

The LINQ provider will not compare by reference the objects stored in db, it will make a deep comparison of every property/field and if objects match, instance will be created.

As you know from one of our first blog posts , we did not implemented this feature for some reasons, the most important one was performance and we suggested to use JOINs instead of nested objects. But ORMs like EntityFramework implemented features like ‘Lazy Loading’ and ‘Eager Loading’, so developer may decide what nested objects will be loaded and when, in this case developer can avoid performance problems depends of app business needs. Well… objects databases vs. ORMs+relational databases is out of scope of this post, but short notice here: Siaqodb store complex objects by keeping pointer/s of childs objects along with object; with this pointer the engine is able to seek directly in database file without any scan or index fetch, so time to look out for nested objects is ZERO, comparing with ORMs+relational dbs it is big difference as performance.
So what if, for example, you want to load orders but you don’t need all nested objects +lists (Customer,OrderLines etc), in this case we let developer configure how objects are loaded so if you set to a certain Type to not load related objects, then all properties(complex types) will not be loaded (will be NULL) by default, but still you may .Include(…) properties like:

            SiaqodbConfigurator.LoadRelatedObjects<Order>(false);
            SiaqodbConfigurator.LoadRelatedObjects<Customer>(false);

 var query1 = siaqodb.Query<Order>().Where(o => o.OrderNumber > 2).Include("OrderCustomer")
                                                                  .Include("OrderCustomer.Address");
//or similar:
  var query2 = (from Order o in siaqodb
                         where o.OrderNumber > 2
                          select o).Include("OrderCustomer").Include("OrderCustomer.Address");

In above queries will be loaded complex properties OrderCustomer and also Address of Customer; Details property will not be loaded.
Look in Examples projects ..\NestedObjectsExample.cs for the complete example.

We hope you enjoy the new features and since this version is in Beta stage we wait for bugs, remarks, suggestions at support at siaqodb com

Siaqodb on Unity3D

We are glad to announce that we successfully port Siaqodb to Unity3D game platform so now our database engine can be used as local database for Unity3D games on PC, Mac, iOS and Android.

Features of Siaqodb for Unity3D:

  • it is fully managed, written completely in C#
  • only one assembly, no 3th party dependencies
  • only two Mono dependencies: System.dll and System.Core.dll
  • small footprint(siaqodb.dll has 240KB)
  • it has very very simple API, LINQ is only query engine (not need to know SQL or other query language)
  • persist your game data with one line of code:
localDB.StoreObject(new Player(){Name="Player1",Score=100}); 
  • and retrieve back using LINQ:
  • var query = from Player p in localDB
                     where p.Name == "playerName" && p.Score>100
                     select p;
    
    
  • your data is stored/retrieved in same way on Windows, Mac, iOS and Android, no code change for specific platform
  • zero config
  • not need Unity3D Pro edition, it works with all Unity3D versions and platforms
  • and many more…

Download Siaqodb for Unity3D now and start using it in your games!
Inside package you will find also a complete demo how Siaqodb may be used for all type of games: PC, Mac, iOS and Android.

And yeah, since we just released we want to offer 20% discount for first 10 purchases, just put “siaqodbUnity3D” as coupon code and discount will be applied, so hurry up!

Siaqodb support now IList and Arrays

Today we released Siaqodb v.2.6, as release notes:

  • Indexes are now persisted in db as AVL tree structured files
  • Support for variable length of String by using TextAttribute
  • Support for blobs (array of byte in efficient way)
  • Support for Array of supported types
  • Support for IList and IList<T>
  • new API method: LoadAllLazy<T>() which load all objects in lazy mode, only when object is accessed by index or by enumerator, it is loaded from db and instance is created.

    Indexes in previous versions was built in background in memory and kept in AVL tree but for very large databases that was still a problem because app may need indexes after db is opened and if they are not yet ready, was not used. Now this problem is solved, indexes are persisted in db as AVL structured file accessing by queries being still as fast as before.

    Variable length of strings: until now Siaqodb stores by default string as max 100 chars, it was also possible to increase that by using MaxLength attribute, but still it was a problem if your strings properties has not appropriate length, one being very big one being small and it was waste of disk space. Now by using Text attribute, string is stored as is, at length it has without any extra byte.

    Support for IList and Array for object members, this was a very demanded feature and staring with this version it is fully supported,also queries over this member are optimized ex:

    public class Post
    {
    public int OID{get;set;}
    public List Tags;
    public string Name;
    }
    ..........................
    
    var query=from Post p in siaqodb
    where p.Tags.Contains("MVVM")
    select p;
    
    

    When above query runs, engine create only instances of Post type which satisfy condition.

    SiaqodbManager support view/edit/add Arrays/Lists too:
    EditArrays

    Download latest version from download page.
    Happy coding ;)

  • 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.