Basic Functionalities

Create/Open Object Server

Create/Get Object Store
StoreFactory.Get method is used for creating (if it doesn't exist yet) or retrieving an object Store from the container.
Sample code for retrieving a Store with basic data type or Xml Serializable Key & Value pair:
//... other code omitted for brevity
var storeFactory = new Sop.StoreFactory();
// MyDictionary Store will be created in the container(server.SystemFile.Store) if it is 
// not found, otherwise factory will load it to memory. Succeeding factory get calls will just return it.
var store = storeFactory.Get<int, string>(server.SystemFile.Store, "MyDictionary");

// StoreFactory.Get(...) method also works for retrieving a Store with Xml Serializable Key and/or Xml Serializable Value pair:
var storeWithXmlSerializeValue = storeFactory.Get<string, XmlSerializableClass>(server.SystemFile.Store, "MyStoreWithXmlSerializableValue");

Sample code for retrieving a Store with Sop.IPersistent interface implementing entities on Key and/or Value pair:
// for retrieving a Store with simple type Key (e.g. - string) & IPersistent Value:
var storeWithPersistentValue = StoreFactory.GetPersistentValue<string, IPersistentImplementingClass>(...);
// for retrieving a Store with IPersistent Key & simple type (e.g. - string) Value:
var storeWithPersistentKey = StoreFactory.GetPersistentKey<IPersistentImplementingClass, string>(...);
// for retrieving a Store with IPersistent Key & IPersistent Value:
var storeWithPersistentKeyValue = StoreFactory.GetPersistent<IPersistentImplementingKeyClass, IPersistentImplementingValueClass>(...);


Delete Object Store

Dispose Object Store
StoreFactory pretty much manages lifetime of object Stores. During high volume load of Stores in memory, more than what can fit in the factory's MRU Store cache, the factory will auto-dispose least recently used Store keeping count of Stores loaded in-memory a handful and not going beyond memory/resource can accomodate (as set in the Profile). However, if the code is sure a certain Store will not be used again, then it is recomended to call Store's Dispose method (or use the using keyword). Sample snippet for illustration:
//... other code omitted for brevity
var storeFactory = new Sop.StoreFactory();
// store will be disposed at end of this block, remove using statement and 
// Factory will manage store's lifetime
using(var store = storeFactory.Get<int, string>(server.SystemFile.Store, "MyDictionary"))
{
    Manage(store);
}
private void Manage(Sop.ISortedDictionary<int, string> store)
{
    store.Locker.Lock();
    store.Add(1, "Hello World!");
    store.Locker.Unlock();
}


Insert Record
Update Record
Delete Records
Search a Record

Query Records
Specify an array of QueryExpressions containing list of Keys and (optional) lambda expression for allowing filter on any of the Value member, allows fine grained querying of entries from the Store. Query returns an array of QueryResult of which each item contains the status whether the respective QueryExpression found a match and if so, also contains the matching entry's Value. Here is a sample code to illustrate simple Query method usage:
// Store declaration, key is long and value is Person entity.
ISortedDictionary<long, Person> PeopleStore;
//... code to instantiate/get/populate the stores were omitted for brevity...
// Query People entities with Ids: 1000, 1001 and output result to People array variable.
QueryResult<long>[] People;
if (PeopleStore.Query(QueryExpression<long>.Package(new long[]{1000, 1001}), out People))
{
    // code to check Query result on "People" variable goes here...
}

Here is another sample code illustrating lambda expression usage for Value filters in the Query method:
// Store declaration, key is string (lastname) and value is Person entity.
ISortedDictionary<string, Person> PeopleStore;
//... code to instantiate/get/populate the stores were omitted for brevity...
// Query People entities with Key (lastname): "Doe" & Person.Phone starts with "510". This output result to People array variable.
QueryExpression<string>[] peopleToSearch = new QueryExpression<string>[]
{
   new QueryExpression<string>
   {
      Key = "Doe",
      // author any function or snippet calling any framework, app or 3rd party library function(s) to extend filter of records based on any Value member(s). Return true for matching records, false otherwise.
      ValueFilterFunc = v => (Person)v.Phone.StartsWith("510")
   }
};
QueryResult<string>[] People;
if (PeopleStore.Query(peopleToSearch, out People))
{
    // code to check Query result on "People" variable goes here...
}



Cursorlike Traversal of Records
Use Movexxx methods (MoveFirst, MoveNext, MovePrevious, MoveLast) and Currentxxx properties (CurrentKey, CurrentValue, CurrentEntry) to navigate from entry to entry in the Store and retrieve Key/Value pair. Combine this cursorlike usage with the Search method for positioning the record pointer to a known entry's key, allows for a very powerful, fine grained data query and processing capability. Index is sure to be 100% utilized as the Store itself serve as the index.

Sequence
Store has a built-in Sequence (long) generator useful for purposes such as generating a unique, identity key to the entity for insert to the Store. CurrentSequence property returns the Store's current (or last generated) sequence value. GetNextSequence method increments (by 1) the current sequence, makes this the new CurrentSequence value and returns the new value to the caller. Sample code:
//... other code omitted for brevity
public class Person
{
    public long Id;
    public string FirstName;
    public string LastName;
}

using (ObjectServer server = ObjectServer.OpenWithTransaction("c:\\SopBin\\OServer.dta"))
{
    var storeFactory = new Sop.StoreFactory();
    var store = storeFactory.Get<long, Person>(server.SystemFile.Store, "PeopleStore");
    Person p = new Person()
    {
        Id = store.GetNextSequence(),
        FirstName = "John",
        LastName = "Doe"
    };
    store.Add(p.Id, p);
    server.Commit();
}


Commit Transaction
Rollback Transaction
Create/Manage File Object

Tracking Stores
Object Server has a feature to track all created Stores in the system. If enabled, code can query or retrieve all of the user created Stores in a given Object Server. This is a useful feature allowing developers ability to get some level of information about each or all available user created Stores in the Server. For each user Store entry, it returns Store's logical UNC path showing its Container hierarchy & File location, member's Key and Value data types. Here is a sample code snippet to do this:
using (ObjectServer server = ObjectServer.OpenWithTransaction("c:\\SopBin\\OServer.dta"))
{
    //... code omitted for brevity
    // set TrackStoreTypes true (default is false if using default profile scheme).
    server.Profile.TrackStoreTypes = true;

    //... code omitted for brevity

    // display list of all user created Stores in the Server
    if (server.StoreTypes != null)
    {
        foreach (var de in server.StoreTypes)
        {
            Console.WriteLine("Store UNC Name: {0}, info: {1}", de.Key, de.Value);
        }
    }
    //... code omitted for brevity
}


Simple Store Navigation
As SOP Stores are hierarchical, a URI path based store retrieval API was created. This should allow developers to focus on authoring Store data retrieval and data management operations and less on navigating the SOP File(s) and their Store/Sub-Store hierarchy.

Auto Create & Read Only Modes
By default, the Store(s) referenced in the Uri path are auto created if not found. Succeeding attempts to navigate/retrieve them will use/return the auto created Store(s). This implicit Store management greatly simplifies Sop Store management and navigation.
However, a parameter to turn off auto Store creation is available useful for readonly use-case.

Sample valid Store URI paths:
"SystemFile/Store1" - implicitly references SystemFile/ObjectStore/Store1
"SystemFile/Store2/Store2.1" - implicitly references SystemFile/ObjectStore/Store2/Store2.1
"SystemFile/Store2/Store2.2"
"SystemFile/Store2/Store2.3/Store2.3.1"
"SystemFile/Store2/Store2.3/Store2.3.2"
...

"File1/Store1/Store1.1" - implicitly references File1/ObjectStore/Store1/Store1.1.
"File1/Store1/Store1.2"
"File2/Store1"
"File2/Store2"
...

Sample code for illustration:
    // Server declaration code was omitted for brevity
    var nav = new Sop.StoreNavigator(Server);
    var store = nav.GetStore<long, Person>("SystemFile/Europe/Spain");
    // code that manages store goes here...

Last edited Mar 17, 2014 at 3:27 AM by grecinto, version 6

Comments

No comments yet.