Skip to content
Leo Botinelly edited this page Dec 2, 2015 · 8 revisions

The simplest possible use of Nyan is as a drop-in ORM storage. In order to test this, follow these steps:

##Setup

  • Create a project
    Since we want something quick and dirty, let's create a Console app:
    File > New > Project > Console Application
    Let's name it NyanSample.

  • Open Nuget Package Manager console
    Now we will download the necessary packages from Nuget.org. Access the Package Manager:
    Tools > Nuget Package Manager > Package Manager console

  • Install Nyan.Core
    Run the following command in the Package Manager Console:
    Install-Package Nyan.Core

  • Choose a data adapter
    Since we want a stand-alone test, let's use an adapter for a DBMS that doesn't require a server to be set up. Microsoft SQL Compact will do just fine:
    Install-Package Nyan.Modules.Data.SQLCompact
    In our sample we won't specify a database name. That's just fine - a default database file called nyanSqlCompactStorage.sdf will be automatically created on the project folder. (You can specify your own database if you want, but that's another topic.)

  • Optional step: Choose a Log provider
    You may want to see what's going on at your backend, so let's install a ZeroMQ log provider:
    Install-Package Nyan.Modules.Log.ZeroMQ

Still here? Good. We're done with Nuget packages. Now, let's set up our...

##Data Model

A basic data model consists of:

  • A class that defines the data to be stored, and
  • Some attributes that defines how the class will behave and work.

In practice, it would look like this:

[MicroEntitySetup(TableName = "Users")]
public class User : MicroEntity<User>
{
    [Key]
    public int id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public bool isAdmin { get; set; }
    public DateTime? BirthDate { get; set; }
}
  • MicroEntity<> ties the User class to Nyan's micro-ORM engine, called MicroEntity.

  • [MicroEntitySetup()] - This attribute describes the way the data will be physically handled. In the sample above, the table that'll store data for the User class is called Users. If the table doesn't exist already, it will be created based on the class' public properties. (You can later change the table column configuration.)

  • [Key] - The Key attribute indicates which field/column will be used to uniquely identify a record in the database. During automatic table creation this attribute is set according to the target database engine's specs - by creating a SEQUENCE tied to a BEFORE INSERT trigger on Oracle, or marking a column as PRIMARY KEY IDENTITY on SQL Server, for example.

  • Nullable type marker - On our example, the BirthDate property is actually a nullable DateTime (DateTime?). That's also reflected on the way the MicroEntity class will handle its data; the table column will also accept NULL values.

Once you have this step done, let's proceed and...

##Play with data##

Since we created a Console app, open up the Program.cs file and type the following:

static void Main(string[] args)
{
    var allUsers = User.Get(); //Press F9 to add a breakpoint here

    var newUser = new User //Press F9 to add another one here
    {
        Name = "Just",
        Surname = "A Test",
        isAdmin = true
    }.Save();
}

Let's fire up our little project! Press F5. If you added the two breakpoints to the solution, you should now be stopped at the allUsers variable definition line. Press F10 to let it run.

...No errors? Good. Hover your mouse over AllUsers variable declaration. You should see something like this:
allUsers | Count = 0

That means that the table was successfully created, and now it's waiting for data. Let's take a peek at the console output:

   |\_/|
  >(o.O)<           Nyan 0.0.1.38510
  c(___)
Settings          : Nyan.Core.Settings.DefaultSettingsPackage
Cache             : Nyan.Core.Modules.Cache.NullCacheProvider
Environment       : Nyan.Core.Modules.Scope.DefaultScopeProvider
Log               : Nyan.Modules.Log.ZeroMQ.ZeroMqLogProvider
Encryption        : Nyan.Core.Modules.Encryption.NullEncryptionProvider
Authorization     : Nyan.Core.Modules.Identity.NullAuthorizationProvider
Global BundleType : Nyan.Modules.Data.SQLCompact.SqlCompactBundle
App Location      : c:\users\localuser\documents\visual studio 2015\Projects\NyanSample\NyanSample\bin\Debug
App Data          : c:\users\localuser\documents\visual studio 2015\Projects\NyanSample\NyanSample\bin\Debug
Stack status      : Operational
NyanSample.Model.User : INIT (Standard)
NyanSample.Model.User : Reading Connection bundle [SqlCompactBundle]
Nyan.Modules.Data.SQLCompact.SqlCompactDataAdapter: Rendering schema element names
NyanSample.Model.User : SqlCeConnection: [c:\users\localuser\documents\visual studio 2015\Projects\NyanSample\NyanSample\bin\Debug\nyanSqlCompactStorage.sdf]
NyanSample.Model.User : SqlCompactDataAdapter is checking database entities
NyanSample.Model.User : Table [Users] not found.
NyanSample.Model.User : Table [Users] created.

Wall of text hits you for 9001 damage! Don't worry, though; the stack is very verbose by default in order to help you detect any boot-up issues. You can later fine tune the verbosity level. But, in short,

  • The stack detected a database adapter basic configuration package (SqlCompactBundle) and a Log provider (ZeroMqLogProvider). Everything else is off - no encryption, no caching, and so on.
  • It managed to boot itself up successfully; that's indicated by the Stack status: Operational line.
  • The SqlCeConnection adapter then proceeds to create a default database, and since the table Users doesn`t exist it s created as well.

Press F10 again, and now hover over the newUser variable definition. This time you'll see a lonely "1" string content. That happens because this method returns the identifier assigned to the new record.

We reached the end of our code. Close the console, and run the project by pressing F5. If you didn't removed the initial breakpoint, press F10 to let the first line execute again. Hover your mouse over AllUsers variable declaration. You should now see something like this:
allUsers | Count = 1

If that's what you see, congratulations! That means that the record you created on the previous session was successfully preserved on your (now slightly used) SQL Compact database.

##Caching##

Ok, we now have a repository. But what about performance? We created a little test block here that creates 100 records and then sequentially reads from the database, by identifier.

Here's the initial numbers:

### Creating 100 records
4046 ms - 24.7157686604053/s
### Reading 100 records
2889 ms - 34.6140533056421/s, 100 records fetched

...which is kind of OK, I guess, for a Compact SQL database receiving 100 individual SELECT statements.

(Remember, you don't need to read records that way: You may use the Get() method without a parameter, which will cause the full table to be loaded and converted to objects. These are the numbers, if you're interested:)

### Reading 100 records, full table
230 ms - 434.782608695652/s, 100 records fetched

Let's try caching read entries now. In order to do so, You'll need to install a Cache provider. Since we're writing a stand-alone application, let's use a Memory cache.

Run the following command in the Package Manager Console:
Install-Package Nyan.Modules.Cache.Memory

For this sample to work, you'll also need to install Faker.Net.Portable - we use it to generate fake data:
Install-Package Faker.Net.Portable

That's all there is to it. Now Let's run the sample code provided - it'll wipe the database, re-create 100 records, read them once (in order to populate the cache) and then try to read them again. Numbers follows:

### Creating 100 records
4076 ms - 24.5338567222767/s
### Reading 100 records, round 1
2897 ms - 34.5184673800483/s, 100 records fetched
### Reading 100 records, round 2
84 ms - 1190.47619047619/s, 100 records fetched
Round 2 was 34.4880952380952 times faster than round 1.

34 times faster. Keep that in mind if you have an application that is heavily read-based - you may benefit from a caching provider. Also, records are purged from the cache after a while (5 minutes by default) or when they're modified.

That's it for our little console sample. Next, we'll see how to implement a REST WebApp.