[ Log In ]

Storing instances of class Person

Person.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VelocityDb;

namespace VelocityDbSchema.Samples.Sample1
{
  public class Person : OptimizedPersistable
  {
    string firstName;
    string lastName;
    UInt16 age;

    public Person(string firstName, string lastName, UInt16 age)
    {
      this.firstName = firstName;
      this.lastName = lastName;
      this.age = age;
    }
  }
}

Program.cs

  class Program
  {
    static readonly string systemDir = 
      System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
      "VelocityDB", "Databases", "Sample1");

    static void Main(string[] args)
    {
      SessionNoServer session = new SessionNoServer(systemDir);
      session.BeginUpdate();
      Person person = new Person("Robin", "Hood", 30);
      session.Persist(person);
      person = new Person("Bill", "Gates", 56);
      session.Persist(person);
      person = new Person("Steve", "Jobs", 56);
      session.Persist(person);
      session.Commit();
    }
  }

Looking at the Person objects through the VelocityDbBrowser

Adding a relation to class Person

Person.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VelocityDb;

namespace VelocityDbSchema.Samples.Sample2
{
  public class Person : OptimizedPersistable
  {
    string firstName;
    string lastName;
    UInt16 age;
    Person bestFriend;

    public Person(string firstName, string lastName, UInt16 age, Person bestFriend = null)
    {
      this.firstName = firstName;
      this.lastName = lastName;
      this.age = age;
      this.bestFriend = bestFriend;
    }

    public Person BestFriend
    {
      get
      {
        return bestFriend;
      }
      set
      {
        Update();
        bestFriend = value;
      }
    }
  }
}

Program.cs

  class Program
  {
    static readonly string systemDir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "VelocityDB", "Databases", "Sample2");

    static void Main(string[] args)
    {
      SessionNoServer session = new SessionNoServer(systemDir);
      session.BeginUpdate();
      Person robinHood = new Person("Robin", "Hood", 30);
      Person billGates = new Person("Bill", "Gates", 56, robinHood);
      Person steveJobs = new Person("Steve", "Jobs", 56, billGates);
      robinHood.BestFriend = billGates;
      session.Persist(steveJobs); // the other persons will be persisted implicetly by reachability from "Steve Jobs" person object
      session.Commit();
    }
  }

Looking at the Sample 2 Person objects through the VelocityDbBrowser

Adding a VelocityDbList to class Person

When using VelocityDbList instreade of List, the list is assigned an Oid instead of being directly embedded in the parent object. If a list is to be shared between multiple objects then VelocityDbList should be used.

Person.cs

 public class Person : OptimizedPersistable
  {
    string firstName;
    string lastName;
    UInt16 age;
    Person bestFriend;
    VelocityDbList<Person> friends;

    public Person(string firstName, string lastName, UInt16 age, Person bestFriend = null)
    {
      this.firstName = firstName;
      this.lastName = lastName;
      this.age = age;
      this.bestFriend = bestFriend;
      friends = new VelocityDbList<Person>();
    }

    public Person BestFriend
    {
      get
      {
        return bestFriend;
      }
      set
      {
        Update();
        bestFriend = value;
      }
    }

    public string FirstName
    {
      get
      {
        return firstName;
      }
      set
      {
        Update();
        firstName = value;
      }
    }

    public VelocityDbList<Person> Friends
    {
      get
      {
        return friends;
      }
    }
  }

Looking at the objects through the VelocityDbBrowser

Main program of Sample4. It also shows how to unpersist (delete from database) objects.

  class Program
  {
    static readonly string systemDir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "VelocityDB", "Databases", "Sample4");

    static void Main(string[] args)
    {
      try
      {
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          session.BeginUpdate();
          Database db = session.OpenDatabase(session.DatabaseNumberOf(typeof(Person)), true, false);
          if (db != null)
          { // delete (unpersist) all Person objects created in prior run
            foreach (Person p in db.AllObjects<Person>())
              p.Unpersist(session);
            // delete (unpersist) all VelocityDbList<Person> objects created in prior run
            foreach (VelocityDbList<Person> l in db.AllObjects<VelocityDbList<Person>>())
              l.Unpersist(session);
          }
          else
          {
            Person robinHood = new Person("Robin", "Hood", 30);
            Person billGates = new Person("Bill", "Gates", 56, robinHood);
            Person steveJobs = new Person("Steve", "Jobs", 56, billGates);
            robinHood.BestFriend = billGates;
            session.Persist(steveJobs);
            steveJobs.Friends.Add(billGates);
            steveJobs.Friends.Add(robinHood);
            billGates.Friends.Add(billGates);
            robinHood.Friends.Add(steveJobs);
          }
          session.Commit();
        }
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.ToString());
      }
    }
  }

OneDbPerClass - an easy and efficient way to persist objects of multiple types

  class OneDbPerClass
  {
    static readonly string systemDir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "VelocityDB", "Databases", "OneDbPerClass");

    public void AddRaceCar()
    {
      try
      {
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          session.BeginUpdate();
          RaceCar raceCar = new RaceCar();
          raceCar.Speed = 1976.7;
          session.Persist(raceCar);
          session.Commit();
        }      
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.ToString());
      }
    }    
    
    public void AddSomeBicycles()
    {
      try
      {
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          session.BeginUpdate();
          for (int i = 0; i < 1000000; i++)
          {
            Bicycle bicycle = new Bicycle();
            bicycle.Color = "red";
            session.Persist(bicycle);
          }
          for (int i = 0; i < 10; i++)
          {
            Bicycle bicycle = new Bicycle();
            bicycle.Color = "blue";
            session.Persist(bicycle);
          }
          for (int i = 0; i < 10; i++)
          {
            Bicycle bicycle = new Bicycle();
            bicycle.Color = "yellow";
            session.Persist(bicycle);
          }
          session.Commit();
        }      
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.ToString());
      }
    }    
    
    public void QuerySomeBicycles()
    {
      try
      {
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          session.BeginRead();
          Database db = session.OpenDatabase(session.DatabaseNumberOf(typeof(Bicycle)));
          var src = from Bicycle bike in db.AllObjects<Bicycle>() where bike.Color == "blue" select bike;
          foreach (Bicycle bike in src)
            Console.WriteLine(bike.ToStringDetails(session));
          session.Commit();
        }      
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.ToString());
      }
    }

    static void Main(string[] args)
    {
      OneDbPerClass oneDbPerClass = new OneDbPerClass();
      oneDbPerClass.AddRaceCar();
      oneDbPerClass.AddSomeBicycles();
      oneDbPerClass.QuerySomeBicycles();
    }
  }

High Availability

The following code shows how high availabilty is achieved using VelocityDB. Test first connects to one server with a requested backup (like replica) to another server. Then we delete all the database files from the original server and quickly make a restore to another server and continue operating with no data loss.

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.IO;
   4:  using System.Linq;
   5:  using System.Net;
   6:  using System.Text;
   7:  using System.Threading.Tasks;
   8:  using VelocityDb;
   9:  using VelocityDb.Session;
  10:  using VelocityDbSchema;
  11:   
  12:  namespace BackupRestore
  13:  {
  14:    class HighAvailability
  15:    {
  16:      static readonly string systemDir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "VelocityDB", "Databases", "HighAvailability");
  17:      static string systemHost = Dns.GetHostName();
  18:      static string backupHost = "FindPriceBuy"; // modify to second server name that you are using (make sure VelocityDB is installed on that server first)
  19:      static readonly string backupDir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "VelocityDB", "Databases", "HighAvailabilityBackup");
  20:   
  21:      public void CreateDataWithBackupServer()
  22:      {
  23:        int loops = 30000;
  24:        int j;
  25:        using (ServerClientSession session = new ServerClientSession(systemDir, systemHost))
  26:        {
  27:          Man aMan = null;
  28:          Woman aWoman = null;
  29:          const bool isBackupLocation = true;
  30:          session.BeginUpdate();
  31:          // we need to have backup locations special since server is not supposed to do encryption or compression
  32:          DatabaseLocation backupLocation = new DatabaseLocation(backupHost, backupDir, (uint)Math.Pow(2, 24), UInt32.MaxValue, session,
  33:            false, PageInfo.encryptionKind.noEncryption, isBackupLocation, session.DatabaseLocations.Default());
  34:          session.NewLocation(backupLocation);
  35:          for (j = 1; j <= loops; j++)
  36:          {
  37:            aMan = new Man(null, aMan, j, DateTime.Now);
  38:            session.Persist(aMan);
  39:            aWoman = new Woman(aMan, aWoman, j);
  40:            session.Persist(aWoman);
  41:            aMan.spouse = new VelocityDb.WeakReference<VelocityDbSchema.Person>(aWoman);
  42:            if (j % 1000000 == 0)
  43:              Console.WriteLine("Loop # " + j);
  44:          }
  45:          UInt64 id = aWoman.Id;
  46:          Console.WriteLine("Commit, done Loop # " + j);
  47:          session.Commit();
  48:        }
  49:      }
  50:   
  51:      public void CreateMoreDataWithBackupServer()
  52:      {
  53:        int loops = 1000;
  54:        int j;
  55:        using (ServerClientSession session = new ServerClientSession(systemDir, systemHost))
  56:        {
  57:          Man aMan = null;
  58:          Woman aWoman = null;
  59:          session.BeginUpdate();
  60:          for (j = 1; j <= loops; j++)
  61:          {
  62:            aMan = new Man(null, aMan, j, DateTime.Now);
  63:            session.Persist(aMan);
  64:            aWoman = new Woman(aMan, aWoman, j);
  65:            session.Persist(aWoman);
  66:            aMan.spouse = new VelocityDb.WeakReference<VelocityDbSchema.Person>(aWoman);
  67:            if (j % 1000000 == 0)
  68:              Console.WriteLine("Loop # " + j);
  69:          }
  70:          UInt64 id = aWoman.Id;
  71:          Console.WriteLine("Commit, done Loop # " + j);
  72:          session.Commit();
  73:        }
  74:      }
  75:   
  76:      public void ReadSomeData()
  77:      {
  78:        int ct = 0;
  79:        using (ServerClientSession session = new ServerClientSession(systemDir, systemHost, true))
  80:        {
  81:          session.BeginRead();
  82:          foreach (Man man in session.AllObjects<Man>())
  83:          {
  84:            ct++;
  85:          }
  86:          Console.WriteLine("Commit, number of Men found: " + ct);
  87:          session.Commit();
  88:        }
  89:      }
  90:   
  91:      public void RestoreToBackupServer()
  92:      {
  93:        using (ServerClientSession session = new ServerClientSession(systemDir, backupHost))
  94:        {
  95:          session.BeginUpdate();
  96:          DatabaseLocation backupLocation = new DatabaseLocation(backupHost, backupDir, (uint)Math.Pow(2, 24), UInt32.MaxValue, session,
  97:      false, PageInfo.encryptionKind.noEncryption, true, session.DatabaseLocations.Default());
  98:          session.RestoreFrom(backupLocation, DateTime.Now);
  99:          session.Commit(false, true);
 100:        }
 101:      }
 102:   
 103:      static void Main(string[] args)
 104:      {
 105:        HighAvailability ha = new HighAvailability();
 106:        ha.CreateDataWithBackupServer();
 107:        ha.ReadSomeData();
 108:        ha.CreateMoreDataWithBackupServer();
 109:        ha.ReadSomeData();
 110:        Directory.Delete(systemDir, true); // remove our current systemDir and all its databases.
 111:        ha.RestoreToBackupServer();
 112:        string t = systemHost; // swap backupHost and systemHost
 113:        systemHost = backupHost;
 114:        backupHost = t;
 115:        ha.ReadSomeData();
 116:      }
 117:    }
 118:  }

Indexes

Here are some classes with defined indexes

{ [Index("modelYear,brandName,modelName,color")]
  public abstract class Vehicle : OptimizedPersistable
  {
    [Index]
    string color;
    int maxPassengers;
    int fuelCapacity; // fuel capacity in liters   
    [Index]
    double litresPer100Kilometers; // fuel cunsumption 
    DateTime modelYear;
    [Index]
    [IndexStringByHashCode]
    string brandName;
    string modelName;
    int maxSpeed; // km/h
    int odometer; // km

    protected Vehicle(string color, int maxPassengers, int fuelCapacity, double litresPer100Kilometers, DateTime modelYear, string brandName, string modelName, int maxSpeed, int odometer)
    {
      this.color = color;
      this.maxPassengers = maxPassengers;
      this.fuelCapacity = fuelCapacity;
      this.litresPer100Kilometers = litresPer100Kilometers;
      this.modelYear = modelYear;
      this.brandName = brandName;
      this.modelName = modelName;
      this.maxSpeed = maxSpeed;
      this.odometer = odometer;
    }

    [FieldAccessor("color")]
    public string Color
    {
      get
      {
        return color;
      }
      set
      {
        Update();
        color = value;
      }
    }

    [FieldAccessor("litresPer100Kilometers")]
    public double LitresPer100Kilometers
    {
      get
      {
        return litresPer100Kilometers;
      }
    }
  }

  [UniqueConstraint]
  [Index("registrationState,registrationPlate")]
  public class Car : Vehicle
  {
    public const UInt32 PlaceInDatabase = 222;

    string registrationState;
    string registrationPlate;
    [Index]
    [UniqueConstraint]
    InsuranceCompany insuranceCompany;
    string insurancePolicy;

    public Car(string color, int maxPassengers, int fuelCapacity, double litresPer100Kilometers, DateTime modelYear,
      string brandName, string modelName, int maxSpeed, int odometer, string registrationState, string registrationPlate,
      InsuranceCompany insuranceCompany, string insurancePolicy):base(color, maxPassengers, fuelCapacity, litresPer100Kilometers, modelYear, brandName, modelName, maxSpeed, odometer)
    {
      this.registrationState = registrationState;
      this.registrationPlate = registrationPlate;
      this.insuranceCompany = insuranceCompany;
      this.insurancePolicy = insurancePolicy;
    }
  }

  [Index("stateOrCountry,licenseNumber")]
  public class DriversLicense : OptimizedPersistable 
  {
    string stateOrCountry;
    string licenseNumber;
    DateTime dateIssued;

    [Index]
    DateTime validUntil;

    public DriversLicense(string stateOrCountry, string licenseNumber, DateTime validUntil)
    {
      this.stateOrCountry = stateOrCountry;
      this.licenseNumber = licenseNumber;
      this.dateIssued = DateTime.Now;
      this.validUntil = validUntil;
    }

    [FieldAccessor("validUntil")]
    public DateTime ValidUntil
    {
      get
      {
        return validUntil;
      }
    }
  }

  public class InsuranceCompany : OptimizedPersistable
  {
    [Index]
    [UniqueConstraint]
    [OnePerDatabase]
    string name;
    string phoneNumber;

    public InsuranceCompany(string name, string phoneNumber)
    {
      this.name = name;
      this.phoneNumber = phoneNumber;
    }

    [FieldAccessor("name")]
    public string Name
    {
      get
      {
        return name;
      }
    }
  }

  [Index]
  public class Person : OptimizedPersistable 
  {
    string name;
    DriversLicense license;

    public Person(string name, DriversLicense license)
    {
      this.name = name;
      this.license = license;
    }
  }

Using these indexes

 class Indexes
  {
    static readonly string systemDir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "VelocityDB", "Databases", "Indexes");

    static void Main(string[] args)
    {
      try
      {
        string brandName = "Toyota";
        string color = "Blue";
        int maxPassengers = 5;
        int fuelCapacity = 40;
        double litresPer100Kilometers = 5;
        DateTime modelYear = new DateTime(2003, 1, 1);
        string modelName = "Highlander";
        int maxSpeed = 200;
        int odometer = 100000;
        string registrationState = "Texas";
        string registrationPlate = "TX343434";
        string insurancePolicy = "CAA7878787";
        DriversLicense license = new DriversLicense("California", "B7788888", DateTime.Now + new TimeSpan(1825, 0, 0, 0));
        Person person = new Person("Mats Persson", license);
        InsuranceCompany insuranceCompany = new InsuranceCompany("AAA", "858787878"); 
        Car car = new Car(color, maxPassengers, fuelCapacity, litresPer100Kilometers, modelYear, brandName, modelName, maxSpeed,
          odometer, registrationState, registrationPlate, insuranceCompany, insurancePolicy);
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          session.BeginUpdate();
          //session.Persist(insuranceCompany);
          session.Persist(car);   
          registrationState = "Maine";
          car = new Car(color, maxPassengers, fuelCapacity, litresPer100Kilometers, modelYear, brandName, modelName, maxSpeed,
          odometer, registrationState, registrationPlate, insuranceCompany, insurancePolicy);
          session.Persist(car);
          color = "Red";
          maxPassengers = 5;
          fuelCapacity = 50;
          litresPer100Kilometers = 8;
          modelYear = new DateTime(2006, 1, 1);
          brandName = "Toyota";
          modelName = "Tacoma";
          maxSpeed = 210;
          odometer = 50000;
          registrationState = "Texas";
          registrationPlate = "TX343433";
          insurancePolicy = "CAA7878777";
          car = new Car(color, maxPassengers, fuelCapacity, litresPer100Kilometers, modelYear, brandName, modelName, maxSpeed,
            odometer, registrationState, registrationPlate, insuranceCompany, insurancePolicy);
          session.Persist(car);
          color = "Black";
          maxPassengers = 5;
          fuelCapacity = 60;
          litresPer100Kilometers = 3;
          modelYear = new DateTime(2001, 1, 1);
          brandName = "Lincoln";
          modelName = "Town Car";
          maxSpeed = 220;
          odometer = 250000;
          registrationState = "Texas";
          registrationPlate = "TX543433";
          insurancePolicy = "CAA7878775";
          car = new Car(color, maxPassengers, fuelCapacity, litresPer100Kilometers, modelYear, brandName, modelName, maxSpeed,
            odometer, registrationState, registrationPlate, insuranceCompany, insurancePolicy);
          session.Persist(car);
          session.Commit();
        }
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          session.BeginRead();
          Console.WriteLine("Blue Cars");
          BTreeSet<Car> bTree = session.Index<Car>("color");
          foreach (Car c in (from aCar in bTree where aCar.Color == "Blue" select aCar))
            Console.WriteLine(c.ToStringDetails(session));
          Console.WriteLine("Cars in fuel efficierncy order");
          foreach (Car c in session.Index<Car>("litresPer100Kilometers"))
            Console.WriteLine(c.ToStringDetails(session));
          Console.WriteLine("Vehicles ordered modelYear, brandName, modelName, color");
          foreach (Vehicle v in session.Index<Vehicle>())
            Console.WriteLine(v.ToStringDetails(session));        
          session.Commit();
        }
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          session.BeginUpdate();
          // these LINQ statements will trigger a binary search lookup (not a linear serach) of the matching Car objects in the BTreeSet
          Car c = (from aCar in session.Index<Car>("color") where aCar.Color == "Blue" select aCar).First();
          c.Color = "Green";      
          session.Commit();
        }
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          session.BeginUpdate();
          // these LINQ statements will trigger a binary search lookup (not a linear serach) of the matching Car objects in the BTreeSet
          Car c = (from aCar in session.Index<Car>("color") where aCar.Color == "Green" select aCar).First();
          UInt64 id = c.Id;
          session.DeleteObject(id);
          session.Abort();
          session.BeginUpdate();
          session.DeleteObject(id);
          session.Commit();
        } 
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          Stopwatch sw = new Stopwatch();
          sw.Start();
          session.BeginRead();
          // these LINQ statements will trigger a binary search lookup (not a linear serach) of the matching Car objects in the BTreeSet
          Console.WriteLine("Blue Cars");
          foreach (Car c in (from aCar in session.Index<Car>("color") where aCar.Color == "Blue" select aCar))
            Console.WriteLine(c.ToStringDetails(session));
          session.Commit();
          sw.Stop();
          Console.WriteLine(sw.Elapsed);
        }        
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          Stopwatch sw = new Stopwatch();
          sw.Start();
          session.BeginUpdate();
          for (int i = 0; i < 10000; i++)
          { // add some junk to make search harder
            car = new Car(color, maxPassengers, fuelCapacity, litresPer100Kilometers, modelYear, brandName, modelName, i,
            odometer, registrationState, registrationPlate, insuranceCompany, insurancePolicy);
            session.Persist(car);
          }
          session.Commit();
          sw.Stop();
          Console.WriteLine(sw.Elapsed);
        }
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          Stopwatch sw = new Stopwatch();
          sw.Start();
          session.BeginRead();
          // these LINQ statements will trigger a binary search lookup (not a linear serach) of the matching Car objects in the BTreeSet
          Console.WriteLine("Blue Cars");
          foreach (Car c in (from aCar in session.Index<Car>("color") where aCar.Color == "Blue" select aCar))
            Console.WriteLine(c.ToStringDetails(session));
          session.Commit();
          sw.Stop();
          Console.WriteLine(sw.Elapsed);
        }  
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          Stopwatch sw = new Stopwatch();
          sw.Start();
          session.BeginUpdate();
          Car c = (from aCar in session.Index<Car>("color") where aCar.Color == "Blue" select aCar).First();
          c.Unpersist(session);
          session.Commit();
          sw.Stop();
          Console.WriteLine(sw.Elapsed);
        }        
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          Stopwatch sw = new Stopwatch();
          sw.Start();
          session.BeginRead();
          foreach (Car c in session.Index<Car>())
            Console.WriteLine(c.ToStringDetails(session));
          Console.WriteLine("Blue Cars");
          foreach (Car c in (from aCar in session.Index<Car>() where aCar.Color == "Blue" select aCar))
            Console.WriteLine(c.ToStringDetails(session));
          session.Commit();
          sw.Stop();
          Console.WriteLine(sw.Elapsed);
        }
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          Stopwatch sw = new Stopwatch();
          sw.Start();
          session.BeginUpdate();
          InsuranceCompany prior = insuranceCompany;
          for (int i = 0; i < 100000; i++)
          {
            insuranceCompany = new InsuranceCompany("AAA", "858787878"); 
            insuranceCompany.Persist(session, prior);
            prior = insuranceCompany;
          }
          session.Commit();
          sw.Stop();
          Console.WriteLine(sw.Elapsed);
        }
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          Stopwatch sw = new Stopwatch();
          sw.Start();
          session.BeginRead();
          Database db = session.OpenDatabase(session.DatabaseNumberOf(typeof(InsuranceCompany)));
          var q = from company in session.Index<InsuranceCompany>("name", db) where company.Name == "AAA" select company;
          foreach (InsuranceCompany company in q)
            Console.WriteLine(company.ToStringDetails(session)); // only one will match
          session.Commit();
          sw.Stop();
          Console.WriteLine(sw.Elapsed);
        }
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.ToString());
      }
    }
  }

Using weak references as a way to limit graph pinned into memory

  public class Person : OptimizedPersistable
  {
    static Random randGen = new Random(5);

    string firstName;
    string lastName;
    WeakReference<VelocityDbList<Person>> friendsRef;

    public Person(Person person = null) // creates a random Person object
    {
      int r = randGen.Next(99999);
      firstName = r.ToString();
      r = randGen.Next(99999999);
      lastName = r.ToString();
      VelocityDbList<Person> personList = new VelocityDbList<Person>();
      if (person != null && person.IsPersistent)
      {
        personList.Persist(person.Session, person);
        personList.Add(person);
        friendsRef = new WeakReference<VelocityDbList<Person>>(personList);
      }
    }

    public string FirstName
    {
      get
      {
        return firstName;
      }
      set
      {
        Update();
        firstName = value;
      }
    }

    public VelocityDbList<Person> Friends
    {
      get
      {
        return friendsRef.GetTarget(false, null);
      }
    }
  }

Usage

  class Program
  {
    static readonly string systemDir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "VelocityDB", "Databases", "WeakReferences");

    const long numberOfPersons = 10000000000; // a billion Person objects - let's say it is more than we can fit in memory
    static void Main(string[] args)
    {
      try
      {
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          session.BeginUpdate();
          Person person = new Person();
          for (long i = 0; i < numberOfPersons; i++)
          {
            // Each WeakReference require a persisted object (non null Oid) so that object reference can be substituted with an Oid.
            session.Persist(person);
            // create new Person and make prior Person his/her friend (see constructor of Person)
            person = new Person(person);
          }
          session.Commit();
        }
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.ToString());
      }
    }

Storing AllSupported instance

The class AllSupported contains sample data fields of all (or most) kinds of types that have beed tested with VelocityDb. Let us know if we missed any kind of field type.

AllSupported.cs

  public class AllSupported : OptimizedPersistable
  {
    enum byteEnum : byte { a, b, c };
    enum int16Enum : short { a, b, c, d, e, f };
    enum int32Enum : int { a, b, c, d, e, f, g, h };
    enum int64Enum : long { a, b, c, dd, ee, ff };
    int[][] jaggedArray = new int[3][];
    Person person; 
    Pet aPet; // just a sample using a class that is not a subclass of OptimizedPersistable
    byteEnum enumByte;
    int16Enum enumInt16;
    int32Enum enumInt32;
    int64Enum enumInt64;
    PersistenceByInterfaceSnake aSnake;
    byte aByte;
    SByte sByte;
    string aString;
    char aChar;
    public float single;
    public double aDouble;
    public UInt16 uint16;
    public UInt32 uint32;
    public UInt64 uint64;
    public Int16 int16;
    public Int32 int32;
    public Int64 int64;
    public DateTime dateTime;
    public TimeSpan timeSpan;
    public Decimal aDecimal;
    byte? nullableByte;
    SByte? nullablesByte;
    char? nullableChar;
    public float? nullablesingle;
    public double? nullableaDouble;
    public UInt16? nullableuint16;
    public UInt32? nullableuint32;
    public UInt64? nullableuint64;
    public Int16? nullableint16;
    public Int32? nullableint32;
    public Int64? nullableint64;
    public DateTime? nullabledateTime;
    public TimeSpan? nullabletimeSpan;
    public Decimal? nullableDecimal;
    WeakReference<OptimizedPersistable> weakReference;
    byte?[] nullablebyteArray;
    char?[] nullablecharArray;
    UInt16?[] nullableuint16Array;
    UInt32?[] nullableuint32Array;
    UInt64?[] nullableuint64Array;
    Int16?[] nullableint16Array;
    Int32?[] nullableint32Array;
    Int64?[] nullableint64Array;
    float?[] nullablefloatArray;
    double?[] nullabledoubleArray;
    DateTime?[] nullableDateTimeArray;
    Decimal?[] nullableDecimalArray;
    Oid?[] nullableOidArray;
    byte[] byteArray;
    char[] charArray;
    UInt16[] uint16Array;
    UInt32[] uint32Array;
    UInt64[] uint64Array;
    Int16[] int16Array;
    Int32[] int32Array;
    Int64[] int64Array;
    float[] floatArray;
    double[] doubleArray;
    DateTime[] dateTimeArray;
    Oid[] oidArray;
    List<byte> listByte; // all List<> use wrapper OptimizedPersistable looked up from a parent collection
    List<Person> personList;
    List<WeakReference<OptimizedPersistable>> weakReferenceList;
    List<Int16> int16List;
    List<UInt16> uint16List;
    List<Int32> int32List;
    List<UInt32> uint32List;
    List<Int64> int64List;
    List<UInt64> uint64List;
    List<String> stringList;
    List<Oid> oidList;
    List<Oid?> nullableoidList;
    [UseOidShort]
    List<Pet> petListOidShort;
    List<Pet> petListLongOid;
    VelocityDbList<byte> odblistByte; // VelocityDbList is like List but is a subclass of OptimizedPersistable which makes it perform better by avoiding collection lookup
    VelocityDbList<Person> personOdbList;
    VelocityDbList<WeakReference<OptimizedPersistable>> weakReferenceOdbList;
    VelocityDbList<Int16> int16OdbList;
    VelocityDbList<UInt16> uint16OdbList;
    VelocityDbList<Int32> int32OdbList;
    VelocityDbList<UInt32> uint32OdbList;
    VelocityDbList<Int64> int64OdbList;
    VelocityDbList<UInt64> uint64OdbList;
    VelocityDbList<String> stringOdbList;
    VelocityDbList<Pet> petOdbList;
    ArrayList petList2;
    public Slot aSlot;
    public Slot[] m_slots;
    BTreeSet<Person> bTreePerson;
    SortedSetAny<Person> sortedSetPerson;
    SortedMap<byte, Person> sortedMapByteToPerson;
    VelocityDbHashSet<Person> personHashSet;
    public struct Slot
    {
      public int hashCode;
      public Person value;
      public int next;
    }
    public AllSupported(Int32 arraySize)
    {
      aSnake = new PersistenceByInterfaceSnake("Curly", 1, true, 58);
      jaggedArray[0] = new int[] { 1, 3, 5, 7, 9 };
      jaggedArray[1] = new int[] { 0, 2, 4, 6 };
      jaggedArray[2] = new int[] { 11, 22 };
      nullabledateTime = null;
      nullableByte = null;
      enumByte = byteEnum.b;
      enumInt16 = int16Enum.c;
      enumInt32 = int32Enum.f;
      enumInt64 = int64Enum.ff;
      byteArray = new byte[arraySize];
      charArray = new char[arraySize];
      uint16Array = new UInt16[arraySize];
      uint32Array = new UInt32[arraySize];
      uint64Array = new UInt64[arraySize];
      int16Array = new Int16[arraySize];
      int32Array = new Int32[arraySize];
      int64Array = new Int64[arraySize];
      floatArray = new float[arraySize];
      doubleArray = new double[arraySize];
      dateTimeArray = new DateTime[arraySize];
      oidArray = new Oid[arraySize];
      nullablebyteArray = new byte?[arraySize];
      nullablecharArray = new char?[arraySize];
      nullableuint16Array = new UInt16?[arraySize];
      nullableuint32Array = new UInt32?[arraySize];
      nullableuint64Array = new UInt64?[arraySize];
      nullableint16Array = new Int16?[arraySize];
      nullableint32Array = new Int32?[arraySize];
      nullableint64Array = new Int64?[arraySize];
      nullablefloatArray = new float?[arraySize];
      nullabledoubleArray = new double?[arraySize];
      nullableDateTimeArray = new DateTime?[arraySize];
      nullableDecimalArray = new Decimal?[arraySize];
      nullableOidArray = new Oid?[arraySize];
      listByte = new List<byte>(arraySize); // just samples of what Key can be
      personList = new List<Person>(arraySize);
      petListOidShort = new List<Pet>(arraySize);
      petListLongOid = new List<Pet>(arraySize);
      petList2 = new ArrayList(arraySize);
      int32List = new List<Int32>(arraySize);
      uint32List = new List<UInt32>(arraySize);
      uint64List = new List<ulong>(arraySize);
      oidList = new List<Oid>(arraySize);
      nullableoidList = new List<Oid?>(arraySize);
      personHashSet = new VelocityDbHashSet<Person>();
      person = new Person();
      timeSpan = new TimeSpan(1, 0, 0);
      aPet = new Cat("Boze", 5);
      petListOidShort.Add(aPet);
      petListLongOid.Add(aPet);
      petList2.Add(aPet);
      uint32List.Add(5555);
      int32List.Add(-66666);
      uint64List.Add(8989898988989);
      doubleArray[0] = 0.2323232323232;
      aSlot = new Slot();
      aSlot.value = new Person();
      m_slots = new Slot[5];
      nullableoidList.Add(new Oid((ulong)4444));
      nullableoidList.Add(null);
      nullableoidList.Add(new Oid((ulong)8888));
      if (arraySize > 0)
      {
        oidArray[0] = new Oid((ulong)99999);
        nullableOidArray[0] = new Oid((ulong)99999);
        nullableint32Array[0] = 5;
      }
      if (arraySize > 2)
      {
        oidArray[2] = new Oid((ulong)66666);
        nullableOidArray[2] = new Oid((ulong)66666);
        nullableint32Array[2] = 6;
      }
      for (int i = 0; i < 5; i++)
      {
        m_slots[i].hashCode = i;
        m_slots[i].value = new Person();
        m_slots[i].next = i + 1;
      }
    }
  }

Pet.cs

  [Serializable]
  public class Pet
  {
    string name;
    short age;
    public List<Pet> friends;
    public Pet() { }
    public Pet(string aName, short anAge)
    {
      name = aName;
      age = anAge;
      friends = new List<Pet>(2);
    }

    public string Name
    {
      get
      {
        return name;
      }
      set
      {
        name = value;
      }
    }
  }

Cat.cs

  [Serializable]
  public class Cat : Pet
  {
    public string color;
    public Cat() { } // used by Activator.CreateInstance for non OptimizedPersistable subclasses and value types
    public Cat(string aName, short anAge, string color = "black") : base(aName, anAge)
    {
      this.color = color;
    }
  }

Main Program of AllSupported sample

  class Program
  {
    static readonly string systemDir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "VelocityDB", "Databases", "AllSupportedSample");
    static void Main(string[] args)
    {
      UInt64 id;
      AllSupported allSupported, allSupported2;
      try
      {
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          session.BeginUpdate();
          allSupported = new AllSupported(3);
          session.Persist(allSupported);
          id = allSupported.Id;
         session.Commit();
        }
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          session.BeginRead();
          allSupported2 = (AllSupported)session.Open(id);
          session.Commit();
        }
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.ToString());
      }
    }
  }

Looking at some of the objects created

SortedObjects

Shows how to use a BTreeSet and a LINQ query taking advantage of the efficient BTreeSet lookup

  class Program
  {
    static readonly string systemDir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "VelocityDB", "Databases", "SortedObjects");

    static void Main(string[] args)
    {
      try
      {
        Oid bTreeId;
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          const UInt32 numberOfPersons = 100000;
          const ushort nodeMaxSize = 5000;
          const ushort comparisonByteArraySize = sizeof(UInt64); // enough room to hold entire idNumber of a Person
          const bool comparisonArrayIsCompleteKey = true;
          const bool addIdCompareIfEqual = false;
          Person person;
          session.BeginUpdate();
          //mySession.SetTraceAllDbActivity();
          CompareByField<Person> compareByField = new CompareByField<Person>("idNumber", session, addIdCompareIfEqual);
          BTreeSet<Person> bTree = new BTreeSet<Person>(compareByField, session, nodeMaxSize, comparisonByteArraySize, comparisonArrayIsCompleteKey);
          session.Persist(bTree); // Persist the root of the BTree so that we have something persisted that can be flushed to disk if memory available becomes low
          for (int i = 0; i < numberOfPersons; i++)
          {
            person = new Person();
            session.Persist(person);
            bTree.Add(person);
          }
          bTreeId = bTree.Oid;
          session.Commit();
        }
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          session.BeginRead();
          BTreeSet<Person> bTree = (BTreeSet<Person>)session.Open(bTreeId);
          foreach (Person person in (IEnumerable<Person>)bTree)
          {
            if (person.IdNumber > 196988888791402)
            {
              Console.WriteLine(person);
              break;
            }
          }
          session.Commit();
          session.BeginRead();
          // this LINQ statement will trigger a binary search lookup (not a linear serach) of the matching Person objects in the BTreeSet
          Console.WriteLine((from person in bTree where person.IdNumber > 196988888791402 select person).First());
          session.Commit();
        }
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.ToString());
      }
    }
  }

DesEncrypted

  class Program
  {
    const UInt32 desEncryptedStartDatabaseNumber = 10;
    const bool compressPages = true;
    static readonly string systemDir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "VelocityDB", "Databases", "DesEncrypted");
    static readonly string desEncryptedLocation = System.IO.Path.Combine(systemDir + "desEncryptedLocation");

    static void Main(string[] args)
    {
      try
      {
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          DatabaseLocation localLocation = new DatabaseLocation(Dns.GetHostName(), desEncryptedLocation, desEncryptedStartDatabaseNumber, UInt32.MaxValue,
            session, compressPages, PageInfo.encryptionKind.desEncrypted);
          session.BeginUpdate();
          session.NewLocation(localLocation);          
          localLocation.DesKey = Page.StringToByteArray("5d9nndwy"); // Des keys are 8 bytes long
          Person robinHood = new Person("Robin", "Hood", 30);
          Person billGates = new Person("Bill", "Gates", 56, robinHood);
          Person steveJobs = new Person("Steve", "Jobs", 56, billGates);
          robinHood.BestFriend = billGates;
          session.Persist(steveJobs);
          steveJobs.Friends.Add(billGates);
          steveJobs.Friends.Add(robinHood);
          billGates.Friends.Add(billGates);
          robinHood.Friends.Add(steveJobs);
          session.Commit();
        }
        using (SessionNoServer session = new SessionNoServer(systemDir))
        { // Des keys are not persisted in DatabaseLocation (for safety). Instead they are stored as *.des files
          // in the users document directory of the user that created the DatabaseLocation. These files can be copied
          // to other user's document directory when acccess is desired for other users. 
          // Path to user document dir is given by C#: Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
          session.BeginRead();
          Database db = session.OpenDatabase(session.DatabaseNumberOf(typeof(Person)));
          foreach (Page page in db)
          {
            foreach (OptimizedPersistable obj in page)
            {
              Person person = obj as Person;
              if (person != null)
                Console.WriteLine(person.FirstName);
            }
          }
          session.Commit();
        }
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.ToString());
      }
    }
  }

UpdateClass

This sample illustrates the support for changing class definition of persistently stored objects

  /// <summary>
  /// Test updating a class that already exist in the Database schema, rerun multiple times. Modify class in between runs. Check objects by browsing them with VelocityDbBrowser
  /// </summary>
  public class UpdateClass
  {
    static readonly string systemDir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "VelocityDB", "Databases", "UpdateClass");

    static void Main(string[] args)
    {
      try
      {
        UpdatedClass updatedClassObject;
        using (SessionNoServer session = new SessionNoServer(systemDir))
        {
          session.BeginUpdate();
          foreach (UpdatedClass obj in session.AllObjects<UpdatedClass>())
          {
            Console.Write(obj.ToString() + " has members: ");
            foreach (DataMember member in (IEnumerable<DataMember>) obj)
            {
              Console.Write(member.ToString() + " ");
            }
            Console.WriteLine();
            //obj.UpdateTypeVersion(); // uncomment if you want to migrate this object to the latest version of the class
          }
          updatedClassObject = new UpdatedClass();
          session.UpdateClass(typeof(UpdatedClass)); // call this when you have updated the class since first storing instances of this type or since last call to UpdateClass
          session.Persist(updatedClassObject);
          session.Commit();
        }
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.ToString());
      }
    }
  }

The class being updated multiple times, UpdatedClass

  // first version of class has:
  //                                    UInt32 aUint32; UInt64 aUint64;                 float aFloat; (1) then
  //                                    UInt32 aUint32; UInt64 aUint64; string aString; float aFloat; (2)
  //                                    UInt32 aUint32;                 string aString; float aFloat; (3)
  //                                    UInt32 aUint32;                                 float aFloat; (4)
  //                    UInt16 aUint16;                                                 float aFloat; (5) 
  //                    UInt16 aUint16; UInt32 aUint32;                                 float aFloat; (6) 
  //                    Int64 aUint16;  UInt32 aUint32;                                 float aFloat; (7) 
  // UpdatedClass aRef; Int64 aUint16;  UInt32 aUint32;                                 float aFloat; (8) 
  //                    Int64 aUint16;  UInt32 aUint32;                                 float aFloat; (9) 
  //                    Int64 aUint16;  UInt32 aUint32;                                 float aFloat; Int32[] intArray; DateTime aDateTime; (10)
  //                    Int64 aUint16;  UInt32 aUint32;                                 float aFloat;                   DateTime aDateTime; (11)
  public class UpdatedClass : OptimizedPersistable 
  {
    //UpdatedClass aRef;
    //Int64 aUint16; 
    //UInt16 aUint16; 
    UInt32 aUint32;
    UInt64 aUint64;
    //string aString;
    float aFloat;
    //Int32[] intArray;
    DateTime aDateTime;

    public UpdatedClass()
    {
      //aRef = this;
      //aUint16 = Int64.MaxValue;
      //aUint16 = UInt16.MaxValue;
      aUint32 = UInt32.MaxValue;
      aUint64 = UInt64.MaxValue;
      //aString = DateTime.Now.ToString();
      aFloat = float.MaxValue;
      //intArray = new Int32[10];
      //aDateTime = DateTime.Now;
    }
  }

Using LINQ

Sometimes it is convenient to use LINQ to get data the way you want it. We use it in the IssueTracker that we have online at VelocityDB.com. As you see deploying an asp.net using VelocityDB is easy. The only issue is updating the host and path of DatabaseLocations used.

public ICollection<ProductVersion> AllVersions(string sortExpression)
    {
      try
      {
        string dataPath = HttpContext.Current.Server.MapPath("~/tracker");
        using (SessionNoServer session = new SessionNoServer(dataPath, false, 2000, true, false))
        {
          session.BeginRead();
          IssueTracker bugTracker = (IssueTracker)session.Open(IssueTracker.PlaceInDatabase, 1, 1, false);
          ICollection<ProductVersion> versionSet = bugTracker.VersionSet.Keys;
          if (sortExpression.Length > 0)
          {
            string[] selectAndDir = sortExpression.Split(' ');
            int sorting = int.Parse(selectAndDir[0]);
            bool reverse = selectAndDir.Length > 1;
            switch (sorting)
            {
              case 1: versionSet = (from version in versionSet orderby version.Name select version).ToList();
                break;
              case 2: versionSet = (from version in versionSet orderby version.Description select version).ToList();
                break;
              case 3: versionSet = (from version in versionSet orderby version.ReleaseDate select version).ToList();
                break;
              case 4: versionSet = (from version in versionSet orderby version.CreatedBy select version).ToList();
                break;
            }
            if (reverse)
            {
              List<ProductVersion> tempList = new List<ProductVersion>(versionSet.Count);
              IEnumerable<ProductVersion> temp = versionSet.Reverse<ProductVersion>();
              foreach (ProductVersion issue in temp)
              {
                tempList.Add(issue);
              }
              versionSet = tempList;
            }
          }
          session.Commit();
          return versionSet;
        }
      }
      catch (System.Exception ex)
      {
        this.errorLabel.Text = ex.ToString();
      }
      return null;
    }

VelocityGraph

This sample is a preview of VelocityGraph, help us define the best possible graph api! The start of this api is inspired by Dex, the sample here mimics what the dex sample is doing. Dex is considered by some to have the best performing graph api currently available. Unlike Dex, which is a C++/C implemented api, VelocityGraph is all implemented in C# and enable any type of Element values. VelocityGraph is provided as open source on GitHub, https://github.com/VelocityDB/VelocityGraph. Anyone is welcome to contribute! VelocityGraph is built on top of VelocityDB. You will need a VelocityDB license to use VelocityGraph. Eventually VelocityGraph may have its own web site, http://www.VelocityGraph.com/

   1:  using System;
   2:  using System.IO;
   3:  using System.Linq;
   4:  using VelocityDb.Session;
   5:  using VelocityGraph;
   6:  using Element = System.Int64;
   7:  using PropertyTypeId = System.Int32;
   8:  using PropertyId = System.Int32;
   9:  using TypeId = System.Int32;
  10:   
  11:  namespace VelocityGraphSample
  12:  {
  13:    class VelocityGraphSample
  14:    {
  15:      static readonly string systemDir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
  16:        "VelocityDB" + Path.DirectorySeparatorChar + "Databases" + Path.DirectorySeparatorChar + "VelocityGraphSample");
  17:   
  18:      static void Main(string[] args)
  19:      {
  20:        if (Directory.Exists(systemDir))
  21:          Directory.Delete(systemDir, true); // remove systemDir from prior runs and all its databases.
  22:        UInt64 graphId;
  23:        using (SessionNoServer session = new SessionNoServer(systemDir, false))
  24:        {
  25:          session.BeginUpdate();
  26:          Graph g = new Graph(session);
  27:   
  28:      // SCHEMA
  29:          // Add a node type for the movies, with a unique identifier and two indexed Propertys
  30:          TypeId movieType = g.NewNodeType("MOVIE");
  31:          TypeId movieIdType = g.NewProperty(movieType, "ID", DataType.Long, PropertyKind.Unique);
  32:          PropertyId movieTitleType = g.NewProperty(movieType, "TITLE", DataType.String, PropertyKind.Indexed);
  33:          PropertyId movieYearType = g.NewProperty(movieType, "YEAR", DataType.Integer, PropertyKind.Indexed);
  34:   
  35:          // Add a node type for the people, with a unique identifier and an indexed Property
  36:          TypeId peopleType = g.NewNodeType("PEOPLE");
  37:          PropertyId peopleIdType = g.NewProperty(peopleType, "ID", DataType.Long, PropertyKind.Unique);
  38:          PropertyId peopleNameType = g.NewProperty(peopleType, "NAME", DataType.String, PropertyKind.Indexed);
  39:   
  40:          // Add an undirected edge type with an Property for the cast of a movie
  41:          TypeId castType = g.NewEdgeType("CAST", false, false);
  42:          PropertyId castCharacterType = g.NewProperty(castType, "CHARACTER", DataType.String, PropertyKind.Basic);
  43:   
  44:          // Add a directed edge type restricted to go from people to movie for the director of a movie
  45:          TypeId directsType = g.NewRestrictedEdgeType("DIRECTS", peopleType, movieType, false);
  46:   
  47:      // DATA
  48:          // Add some MOVIE nodes
  49:   
  50:          Element mLostInTranslation = g.NewNode(movieType);
  51:          g.SetProperty(mLostInTranslation, movieIdType, (long) 1);
  52:          g.SetProperty(mLostInTranslation, movieTitleType, "Lost in Translation");
  53:          g.SetProperty(mLostInTranslation, movieYearType, (int) 2003);
  54:   
  55:          Element mVickyCB = g.NewNode(movieType);
  56:          g.SetProperty(mVickyCB, movieIdType, (long) 2);
  57:          g.SetProperty(mVickyCB, movieTitleType, "Vicky Cristina Barcelona");
  58:          g.SetProperty(mVickyCB, movieYearType, (int) 2008);
  59:   
  60:          Element mManhattan = g.NewNode(movieType);
  61:          g.SetProperty(mManhattan, movieIdType, (long) 3);
  62:          g.SetProperty(mManhattan, movieTitleType, "Manhattan");
  63:          g.SetProperty(mManhattan, movieYearType, (int) 1979);
  64:   
  65:   
  66:          // Add some PEOPLE nodes
  67:          Element pScarlett = g.NewNode(peopleType);
  68:          g.SetProperty(pScarlett, peopleIdType, (long) 1);
  69:          g.SetProperty(pScarlett, peopleNameType, "Scarlett Johansson");
  70:   
  71:          Element pBill = g.NewNode(peopleType);
  72:          g.SetProperty(pBill, peopleIdType, (long) 2);
  73:          g.SetProperty(pBill, peopleNameType, "Bill Murray");
  74:   
  75:          Element pSofia = g.NewNode(peopleType);
  76:          g.SetProperty(pSofia, peopleIdType, (long) 3);
  77:          g.SetProperty(pSofia, peopleNameType, "Sofia Coppola");
  78:   
  79:          Element pWoody = g.NewNode(peopleType);
  80:          g.SetProperty(pWoody, peopleIdType, (long) 4);
  81:          g.SetProperty(pWoody, peopleNameType, "Woody Allen");
  82:   
  83:          Element pPenelope = g.NewNode(peopleType);
  84:          g.SetProperty(pPenelope, peopleIdType, (long) 5);
  85:          g.SetProperty(pPenelope, peopleNameType, "Penélope Cruz");
  86:   
  87:          Element pDiane = g.NewNode(peopleType);
  88:          g.SetProperty(pDiane, peopleIdType, (long) 6);
  89:          g.SetProperty(pDiane, peopleNameType, "Diane Keaton");
  90:   
  91:          // Add some CAST edges
  92:          Element anEdge;
  93:          anEdge = g.NewEdge(castType, mLostInTranslation, pScarlett);
  94:          g.SetProperty(anEdge, castCharacterType, "Charlotte");
  95:   
  96:          anEdge = g.NewEdge(castType, mLostInTranslation, pBill);
  97:          g.SetProperty(anEdge, castCharacterType, "Bob Harris");
  98:   
  99:          anEdge = g.NewEdge(castType, mVickyCB, pScarlett);
 100:          g.SetProperty(anEdge, castCharacterType, "Cristina");
 101:   
 102:          anEdge = g.NewEdge(castType, mVickyCB, pPenelope);
 103:          g.SetProperty(anEdge, castCharacterType, "Maria Elena");
 104:   
 105:          anEdge = g.NewEdge(castType, mManhattan, pDiane);
 106:          g.SetProperty(anEdge, castCharacterType, "Mary");
 107:   
 108:          anEdge = g.NewEdge(castType, mManhattan, pWoody);
 109:          g.SetProperty(anEdge, castCharacterType, "Isaac");
 110:   
 111:          // Add some DIRECTS edges
 112:          anEdge = g.NewEdge(directsType, pSofia, mLostInTranslation);
 113:          anEdge = g.NewEdge(directsType, pWoody, mVickyCB);
 114:          anEdge = g.NewEdge(directsType, pWoody, mManhattan);
 115:   
 116:      // QUERIES
 117:          // Get the movies directed by Woody Allen
 118:          Elements directedByWoody = g.Neighbors(pWoody, directsType, EdgesDirection.Outgoing);
 119:   
 120:          // Get the cast of the movies directed by Woody Allen
 121:          Elements castDirectedByWoody = g.Neighbors(directedByWoody, castType, EdgesDirection.Any);
 122:   
 123:   
 124:          // Get the movies directed by Sofia Coppola
 125:          Elements directedBySofia = g.Neighbors(pSofia, directsType, EdgesDirection.Outgoing);
 126:   
 127:          // Get the cast of the movies directed by Sofia Coppola
 128:          Elements castDirectedBySofia = g.Neighbors(directedBySofia, castType, EdgesDirection.Any);
 129:   
 130:          // We want to know the people that acted in movies directed by Woody AND in movies directed by Sofia.
 131:          Elements castFromBoth = Elements.CombineIntersection(castDirectedByWoody, castDirectedBySofia);
 132:   
 133:          // Say hello to the people found
 134:          foreach (Element peopleOid in castFromBoth)
 135:          {
 136:            object value = g.GetProperty(peopleOid, peopleNameType);
 137:            System.Console.WriteLine("Hello " + value);
 138:          }
 139:          graphId = session.Persist(g);
 140:          session.Commit();
 141:        }
 142:   
 143:        using (SessionNoServer session = new SessionNoServer(systemDir, false))
 144:        {
 145:          session.BeginRead();
 146:          Graph g = (Graph) session.Open(graphId);
 147:          TypeId movieType = g.FindType("MOVIE");
 148:          PropertyId movieTitleProperty = g.FindProperty(movieType, "TITLE");
 149:          Element obj = g.FindElement(movieTitleProperty, "Manhattan");
 150:          session.Commit();
 151:        }
 152:      }
 153:    }
 154:  }

Wikipedia

Here we import the entire collection of Wikipedia articles/subjects. Wikipedia is available as one giant XML file, the file is 40 GB large (uncompressed). You can download the compressed file (~9 GB) from here. Uncompress it using 7-zip. The import to VelocityDB databases is very fast, it takes about 20 minutes to read, parse and store all 652,870,281 lines of text into 80 structured VelocityDB databases (from & to a spinning disk). The sample program then continues by creating an inverted index of all 12,772,300 Wikipedia articles, the index is created using parallell threads. All the C# source code for this sample is provided in our download.

WorldCities

Loads World Cities with population from a csv file (~about 2.7 million records) provided by MaxMind. After loading the city data, we attempt to mimic the behavior of QlikView. A ListBoxItem that is selected has a green background, an associated value has a white background and non-associated values have a light gray background. You can select single cells or multiple cells in each column and see how the associations (colors) change. QlikView is a very successful product with revenue around $260 million/year. The product was invented and mostly coded by my fellow Swede, Håkan Wolgé

ImdbImport and KevinBaconNumbers

ImdbImport imports from two compressed text files containing actors, actresses and movie data. The data comes from IMDB


The KeveinBaconNumers application computes the degree of seperation between Kevin Bacon and all other actors and actresses (~ 2 million) taking part in about 350,000 movies.

0 degrees means you are Kevin Bacon

1 degree, you acted in one of Kevin Bacon's movies

2 degrees, you acted in a movie with someone who acted in the same movie as Kevin Bacon

and so on...


The output looks similar to Oracle of Bacon (which by the way is not using an Oracle database!)


[c:\VelocityDb\Release]timer& KevinBaconNumbers.exe& timer

Timer 1 on: 12:07:04

Degree 0 has # of people: 1

Degree 1 has # of people: 3475

Degree 2 has # of people: 385345

Degree 3 has # of people: 894996

Degree 4 has # of people: 121903

Degree 5 has # of people: 7462

Degree 6 has # of people: 446

Degree 7 has # of people: 28

Degree 8 has # of people: 0

Degree 9 has # of people: 0

Timer 1 off: 12:07:33 Elapsed: 0:00:29.81


The entire C# source code for these two applications are part of the download of VelocityDB, download it for free from here.

 

We ran this on a desktop PC, the same one that was used for the triangle counter.


How would you compute this matrix using only SQL code? We bet it wouldn't compute as fast, the entire matrix is calculated in less than half a minute using VelocityDB.

VelocityDbBrowser

Shows how to display persistent objects using an asp TreeView control. We are making the source code public so that you can help us improve the browser. Suggestions are welcome.

Text Indexer

This is a mini web crawler that grabs the text from selected web sites and shows which words are used and how frequently. I tried to use teqniques as described in a paper by the Google founders. Did I do it right? Help me out!

The TextIndexer has been extended to also indexing local text files. We downloaded some free complete books from Top 100 - Project Gutenberg

Baseball statistics

This sample applications imports Baseball statistics data from csv files provided by Sean Lahman

NUnit tests

We are including some NUnit tests. These tests should further help explaining how use the VelocityDb API. New NUnit tests are welcome! The NUnit GUI driver is awesome!

Issue Tracker

There are some good bug tracking software out there but we needed a more complete sample application so we build my own issue (bug) tracking system. Please help us improve this application so that it feels more complete. We will make the src code available for the issue tracker as soon as possible. (We need to split it up from the rest of VelocityDb.com). Let us know if you want it.

Please help

By working together we can improve the samples. We develop using git as a source control tool. We will setup a repository on GitHub or a similar site until then please email us suggestions and C# sample code. Alternativly, you can use the Isuue tracker and open an issue describing an improvement or a bug. You can attach files to an issue. Email to: Samples@VelocityDB.com