📜 ⬆️ ⬇️

Eloquera 4

Brief base description


From the very beginning, the Eloquera database was written to store objects based on the .Net Framework, which made it possible to try to absorb all the best from object and relational databases at the same time, overcoming many of their differences. Theoretically, Eloquera can work with any languages ​​from the .Net Framework family, however, in practice, the work has been checked so far only with C #. The main focus of developers on the enterprise segment (100+ GB), and not on the embedded solution, although the latter are also not deprived of attention.

The distinctive features of Eloquera are very impressive and are constantly replenished, here is a very short list of them:


Installation


You can pick up base distribution kits from the official website www.eloquera.com after registration. You can choose from archives for the desktop installation and for installation as a service (x86 or x64). When installing Eloquera as a service, there are no pitfalls.

Installation on any more or less modern machine will take no more than 5 minutes. After which at your disposal will be:

The desktop version is installed on the x-copy principle, i.e. you just need to copy the files to the desired directory. To work, you will need the .Net 4 Full Framework installed.
')
With this approach, the NuGet package looks quite expected, but at the moment there is no such thing yet. However, the developers are aware of this possibility and are threatening to create such a project soon, as soon as the kernel for the standalone version of the base is formatted as a library and not an executable file.

Base Modes


Eloquera DB can work in several modes:

Code to connect to the server and create a database:
private const string DBName = "ServiceDatabase"; using (var eloquera = new DB("server=localhost:43962;options=none;")) { eloquera.CreateDatabase(DBName); eloquera.OpenDatabase(DBName); eloquera.Close(); } 

The DB class is used to connect to the database . The class constructor is passed the connection string, in this example the connection goes to the service.

Eloquera supports in-memory mode as when working as a service, and when working offline (desktop mode). In the free version, the base in memory can take up to 1 GB. It is also worth remembering about the physical availability of RAM, as it is possible that the size of the database will be such that Windows will try to place it in the paging file on the disk. As you know, this does not add speed at all.

In order to indicate to the engine that we want to create a database in RAM, it will be necessary to specify a special inmemory parameter in the connection string.
 new DB("server=(local); options=inmemory;")) 

In this case, the database will exist only in RAM, but an empty file will still be created in the file system . In order to be able to resume work with such a database, you must use the persist parameter in the connection string in the options

For work in desktop mode, the connection string will be:
 new DB("server=(local); options=none;")) 

In order for Eloquera to work in Desktop mode, you need to stop the EloqueraDB service, otherwise you will get an error saying that it is impossible to connect to the service at the address (local).

A lot of interesting things in the database, but I will stop on the most interesting probably.

JOINs


The general syntax of the operation:
 SELECT Alias1,Alias2 FROM Type1 Alias1 [ LEFT | RIGHT| INNER | FULL ] JOIN Type2 Alias2 ONSomeFunction(Alias1.Field1, Alias2.Field2) 

If two different types or more were used in building a query using JOIN in a SELECT, then the result of such an operation will be a new IEnumerable <Dictionary <string, object >>.

JOIN queries, like other types of queries, can use named parameters. Including in the expression ON. However, there are some limitations to keep in mind:

We should also mention how the issue is solved with the heirs of the classes involved in the construction of the JOIN expression. The standard behavior is considered the possibility of using inherited types in a query. For example, if TypeC is inherited from TypeA, then the expression:
 SELECT a, b FROM TypeA a INNER JOIN TypeB b ON b.id = a.id 

can return TypeC objects in the “a” field if they satisfy the conditions of the expression. In order to get rid of all the descendants of the class in the query results, you should use the word ONLY. Those. rewrite the query like this:
 SELECT a, b FROM ONLY TypeA a INNER JOIN TypeB b ON b.id = a.id 

Now in the "a" will be only objects of type TypeA.

Example in pictures to work Inner Join. Suppose we have the following data structure:

Our task is to find all the schools and jobs that are in one place.
Code:
 var queryResult = (IEnumerable<Dictionary<string,object>>) db.ExecuteQuery("SELECT sch, wp FROM School sch INNER JOIN WorkPlace wp ONch.Location=wp.Location"); 

The results in the form of a table can be represented as follows:
#
queryResult [“sch”]
queryResult [“wp”]
one
School1
wPlace2
2
School2
wPlace2
3
School3
wPlace3
four
School3
wPlace4

Options


Parameters can only be used to transfer data to a request, so it’s useless to fantasize about getting data through parameters.

Using parameters is very simple:
 Parameters param = db.CreateParameters(); param["name"] = "John" 

To use a parameter in a request, you must use an overloaded method that accepts them. For example:
 var res = db.ExecuteQuery("SELECT BasicUser WHERE Name = @name", param); 

The array of parameter values ​​can be interpreted by the base as a simple array:
 Parameters param = db.CreateParameters(); param.AddList("emails", new string[]{"john@gmail.com", "david@hotmail.com"}); var res = db.ExecuteQuery("SELECT BasicUser WHERE ALL @emails in Emails", param); 

Parameters can be used with Top, Skip and Order By. Parameters can also contain null.

Stored procedures


Starting with version 4.0, Eloquera supports stored procedures.

Stored procedures can be considered as extension methods to the main base. They are written using C #, for which thanks to the creators, for not having invented any of their interpretable dialect for this business. It turns out that you can use the entire .Net feature when writing procedures.

So, words suffice, it is better to show how stored procedures are created in practice.

The first step is to declare the interface with the desired procedures. This interface must be on the client and server side.
 public interface ICityStatisticSP{ CityCars GetCityCars(string cityName); } 

Then we create a class that will be needed only on the server side. In this case, the library with the implementation of the procedure must be placed in the Lib folder in the base directory, or the path to the libraries with stored procedures can be configured using the StoredProceduresPath parameter.
 public class CityStatisticSP: StoredProcedure, ICityStatisticSP { public CityCars GetCityCars(string cityName) { Parameters parms = db.CreateParameters(); parms["city"] = cityName; var cars = db.ExecuteQuery("SELECT Car FROM Car JOIN Seller ON Car.SellerID = Seller.ID WHERE Seller.City = @city", parms) .OfType<Car>() .ToList(); … } } 

Adding new procedures does not require restarting the database service.

After you have thrown the library with the procedures to the server, you can call the procedure on the client with the following code:
 ICityStatisticSP procedures = db.GetStoredProcedureClass<ICityStatisticSP>(); string cityName = "Chicago"; CityCars cars = procedures.GetCityCars(cityName); 

Based on the very object nature of the database, it is not necessary to configure the mapping configuration procedure and other things-other things.

The presence of stored procedures in the existing form solves more complex problems than the simple saving and re-invoking requests to the database. It is worth emphasizing that all code is executed on the side of the base . Those. With the help of procedures, you can greatly reduce the load on the network, when using procedures you can more effectively filter data on the server side, based on the results of filtering, for example, create new elements and store them in the database. I think that it is not difficult to imagine a situation when it is necessary to add a set of elements from the base with some value. Under the old approach, we would have to unload all the elements, create a selection of conditions for updating, update, and transfer the new data back to the network. The stored procedure will solve such problems much more efficiently.

Dynamic objects (Dynamic)


According to the developers of Eloquera, they added a bit of magic to the object base and got a unique functionality and object, which was called Dynamic. You have already guessed where the legs grow from this feature, and with which it is ideologically aligned in C #. Dynamic objects can store in themselves as structured data, i.e. classes and structures defined by you in C # code, and arbitrarily compiled. At the same time, you can freely represent these objects as each other.

The main advantage is the ability to add and remove fields from a saved object - the data will magically join and integrate into the object.
Advantages that provide dynamic objects:

Regarding the last two points, it is necessary to clarify that we mean various programs that allow users to independently construct data types, dynamically make up an interface for each user. There is no rational possibility to keep such data in strict form without explosive complexity. Using Dynamic allows you to describe such types in an infinite variety and work with them in the same style.

Another example is Web 2.0, where users can add their own comments to everything, associate materials, and so on. With traditional relational databases, hard class descriptions, such schemes are impossible or very difficult to implement.

A quick overview of working with dynamic objects


The structure of dynamic objects can be modified at any time along with the contained data. Together with ease of use, it provides more than ample opportunities for data evolution.
 Dynamic @do = new Dynamic(); @do["Title"] = "Some title"; @do["Price"] = 14.99; @do["DateAdded"] = DateTime.Now; db.Store(@do); Dynamic res = (from Dynamic d in db where d["Price"] == 14.99 select d).First<Dynamic>(); 

The same is possible with the use of variables of type dynamic presented in .Net 4.
 dynamic @do = new Dynamic(); @do.Title = "Some title"; @do.Price = 14.99; @do.DateAdded = DateTime.Now; db.Store(@do); dynamic res = (from Dynamic d in db where d["Price"] == 14.99 select d).First<Dynamic>(); 

Please note that when using LINQ, you must use d [“Price”] to explicitly indicate the construction of the expression tree.

When working with dynamic objects, it is possible to find out all the fields that the object contains:

 Dynamic @do = dynamics[0]; foreach (var field in @do) { Console.WriteLine(String.Format("Field Name {0} Value {1} Type {2}", field.Key, field.Value, field.Type)); } 

In addition to the wide possibilities, there are some limitations, in particular, there is a list of characters that cannot be used when specifying field names. This is aimed at avoiding collisions while writing SQL queries to objects. Here is a list of reserved characters:

.,%] [+ - $! * ()

I hope that you will be interested in the base and at least take a base on a note for home experiments.

I can organize a cycle of articles if it is interesting, the material is ready.

Source: https://habr.com/ru/post/128475/


All Articles