We are very proud to announce that we finally ported Siaqodb to .NET profile for Metro style apps (NETFX_CORE) and fully async API. We have ported previously on several platforms but now it took longer because about 80% of the methods had to be rewritten. Until now we have used in our code preprocessor directives like #IF SILVERLIGHT, #IF MonoTouch etc, because it was easier to maintain in this way Siaqodb sources for multiple platform, but NETFX_CORE could not be used in a similar way because the sources are changed too much as result of a few things, most important:
1.”async methods”
2. Reflection changes
We know portable class library but shortly: it doesn’t work for Siaqodb.
To pass validation for Windows 8 App Store, your Metro style app should call all the I/O operations async, which means a lot for the Siaqodb library. The methods that may fall into calling a I/O operation must be async and they have to be called with “await” in case you need the result returned for further processing; and await can be used only in a async method, so all methods from the lowest layer to the uppermost layer must be async.
Another important aspect for Metro style apps:
“A Metro style app runs in a security container with limited access to the file system, network resources, and hardware. Whenever a user installs an app from the Windows Store, Windows looks at the metadata in the Package.appxmanifest file to figure out what capabilities the app needs to function. For example, an app might need to access data from the Internet, documents from the user’s Document Library, or the user’s webcam and microphone. When the app is installed, it displays to the user the capabilities it needs, and the user must grant permission for it to access those resources. If the app doesn’t request and receive access to a resource it needs, it will not be allowed access to that resource when the user runs it.”
(source MSDN)
Just as you can access in Silverlight the IsolatedStorage, in a similar way you will have full and unrestricted access to app’s local folder found in C:\Users\\AppData\Local\Packages\. Here you can create, modify and delete files and folders without asking user’s permission. Local data access is provided using Windows.Storage.ApplicationData.
So, for opening a Siaqodb database you have to pass as database name the folder where your data will be stored like:
Siaqodb siaqodb = new Siaqodb();
await siaqodb.Open(ApplicationData.Current.LocalFolder);
As you know the only query engine for Siaqodb is LINQ and Siaqodb LINQ provider is implemented by extending IEnumerable interface; bad news is that currently there is not shipped any IAsyncEnumerable interface that would support LINQ and also having a method signature like
public async Task> GetEnumerator()
or/and IAsyncEnumerator where MoveNext() method is async, and -very important- Microsoft says that such a interface/s will not be shipped for now.
So we had to find a way to use LINQ but also to load objects from database async as result of that LINQ statement. We’ve made our IAsyncEnumerator which is used by most methods within our LINQ provider. The ISqoQuery interface still implements IEnumerable but when it’s called its GetEnumerator() method, an exception is thrown and client API must use our X_Async() methods instead. Basically we parse lambda expression in the same way as we did before, but when objects need to get materialized, we should call an async method since it may fall in a I/O operation.
For the standard .NET version, Siaqodb LINQ provider can optimize following LINQ operations by re-defining new methods for:
Any(...)
Count(...)
First(...)
FirstOrDefault(...)
Join(...)
Last(...)
LastOrDefault(...)
OrderBy(...)
OrderByDescending(...)
Select(...)
Single(...)
SingleOrDefault(...)
Take(...)
ThenBy(...)
ThenByDescending(...)
Skip(...)
Where(...)
Most of the methods above will throw exceptions now, but the following methods must be used for Siaqodb for Metro Style apps:
AnyAsync(...)
CountAsync(...)
FirstAsync(...)
FirstOrDefaultAsync(...)
LastAsync(...)
LastOrDefaultAsync(...)
OrderBy(...)
OrderByDescending(...)
Select(...)
SingleAsync(...)
SingleOrDefaultAsync(...)
TakeAsync(...)
ThenBy(...)
ThenByDescending(...)
SkipAsync(...)
Where(...)
And to get result of a LINQ query that returns ISqoQuery you always have to call ToListAsync() method, otherwise, fetching the IEnumerable will throw exception.
So let’s see some code:
Siaqodb siaqodb = new Siaqodb();
await siaqodb.Open(ApplicationData.Current.LocalFolder);
//store the first person
await siaqodb.StoreObject(new Person() { FirstName = "Michael", LastName = "Smith" };);
//load all persons stored in database
var allPersons=await siaqodb.LoadAll<Person>();
//make a LINQ query
var persons=await(from Person pers in siaqodb
where pers.FirstName=="Michael"
select pers).ToListAsync();
The current version is in BETA stage, you can download it and use it as trial for 90 days
The Indexes are the only missing feature in this version( but still read performance is very good), all the rest of features of Siaqodb 3.2.0.5 are included in the Siaqodb for Metro style apps.
Very important, we ported also all UnitTests and all passed!
Since this is a BETA version, we wait for your feedback, so if you have questions/remarks shout us at support at siaqodb dot com.
So go to our download page and grab it now, you have a lot of examples that can be found in MetroExample project included in the setup!