Published by marco on
One part of Quino that has undergone quite a few changes in the last few versions is the data driver. The data driver is responsible for CRUD: create, read, update and delete operations. One part of this is the ORM—the object-relational mapper—that marshals data to and from relational databases like PostgreSql, SQL Server and SQLite.
We’re going to cover a few topics in this series:
But first let’s take a look at an example to anchor our investigation.
An application makes a request to the data driver using commands like Save()
to save data and GetObject()
or GetList()
to get data. How are these high-level commands executed? Quino does an excellent job of shielding applications from the details but it’s still very interesting to know how this is achieved.
The following code snippet creates retrieves some data, deletes part of it and saves a new version.
using (var session = application.CreateSession())
{
var people = session.GetList<Person>();
people.Query.WhereEquals(Person.Fields.FirstName, "john");
session.Delete(people);
session.Save(new Person { FirstName = "bob", LastName = "doe" });
}
In this series, we’re going to answer the following questions…and probably many more.
Let’s tackle the last two questions first.
The application defines common configuration information. The most important bits for the ORM are as follows:
Person
, which has at least the two properties LastName
and FirstName
. There is probably an entity named Company
as well, with a one-to-many relationship to Person
. As you can imagine, Quino uses this information to formulate requests to data stores that contain data in this format.[1] For drivers that support it, Quino also uses this information in order to create that underlying data schema.[2]So that’s the application. There is a single shared application for a process.
But in any non-trivial application—and any non-desktop application—we will have multiple data requests running, possibly in different threads of execution.
That’s where sessions come in. The session encapsulates a data context, which contains the following information:
HttpContext.Current.User
but generalized to be available in any Quino application. All data requests over a session are made in the context of this user.If we go back to the original code sample, we now know that creating a new session with CreateSession()
creates a new data context, with its own user and its own data cache. Since we didn’t pass in any credentials, the session uses the default credentials for the application.[3] All data access made on that session is nicely shielded and protected from any data access made in other sessions (where necessary, of course).
So now we’re no closer to knowing how Quino works with data on our behalf, but we’ve taken the first step: we know all about one of the main inputs to the data driver, the session.
In the next part, we’ll cover the topic “The Data Pipeline”.
Person.Fields.FirstName
in the example), or view models, DTOs or even client-side TypeScript definitions. We also use the model to generate user interfaces—both for entire desktop-application interfaces but also for HTML helpers to build MVC views.↩This is code that you might use in a single-user application. In a server application, you would most likely just use the session that was created for your request by Quino. If an application wants to create a new session, but using the same user as an existing session, it would call:
var requestCredentials = requestSession.AccessControl.CurrentUser.CreateCredentials();
using (var session = application.CreateSession(requestCredentials))
{
// Work with session
}
↩