Tag - Database

Entries feed - Comments feed

2011-08-08

Our mORMot won't hibernate this winter, thanks to FireMonkey

Everybody is buzzing about FireMonkey...

Our little mORMot will like FireMonkey!
Here is why...

Continue reading

2011-07-25

Close future of the framework: database agnosticism

Our ORM RESTful Framework is about to access any available database engine.

It will probably change its name (since it won't use only SQlite3 as database), to become mORMot - could be an acronym for "Manage Object Relational Mapping Over Tables", or whatever you may think of...

We'll still rely on SQLite3 on the server, but a dedicated mechanism will allow to access via OleDB any remote database, and mix those tables content with the native ORM tables of the framework. A flexible Virtual Tables and column mapping will allow any possible architecture: either a new project in pure ORM, either a project relying on an existing database with its own table layout.

Continue reading

2011-07-22

SynDBSQLite3: SQLite3 direct access

For our ORM framework, we implemented an efficient SQLite3 wrapper, joining statically (i.e. without any external dll) the SQLite3 engine to the executable. SQLite3 is in fact used as the DB kernel of the framework. For instance, thanks to its unique virtual table mechanism, even tables in other databases (like Oracle or MSSQL) are available as if they were SQLite3 tables.

We just made this wrapper independent from our ORM, in a new dedicated unit, named SynSQLite3.pas.

It was an easy task to let this unit be called from our SynDB database abstract classes.

Continue reading

2011-07-03

"Sharding" or "Share nothing" architecture

Here is what wikipedia states at http://en.wikipedia.org/wiki/Shared_nothing_architecture:

A shared nothing architecture (SN) is a distributed computing architecture in which each node is independent and self-sufficient, and there is no single point of contention across the system. People typically contrast SN with systems that keep a large amount of centrally-stored state information, whether in a database, an application server, or any other similar single point of contention.

This is just one approach of "sharding". Sharding is indeed related to a shared nothing architecture - once sharded, each shard can live in a totally separate logical schema instance.
"I sharded, therefore it scales"...

You can do this in Delphi... and opens a new world of scaling opportunities... Just as Google, Facebook, or eBay do... 

Continue reading

2011-07-02

Is Object-Relational Mapping the Paradise of Computer Science?

There is a well known syndrome around, against ORM.

Do you remember The Vietnam of Computer Science article?

It is worth reading... and commenting.
Sounds a bit outdated by now. Tempus fugit!

Continue reading

Faster variant late binding

For both our SynOleDB and SynBigTable units, we allow late-binding of data row values, using a variant and direct named access of properties. Thanks to this unique feature (as far as I know in the Delphi database world),

This allows clear and valid code as such:

var Customer: Variant;
begin
  with Props.Execute(
    'select * from Sales.Customer where AccountNumber like ?',
    ['AW000001%'],@Customer) do
    while Step do
      assert(Copy(Customer.AccountNumber,1,8)='AW000001');
end;

In practice, this code is slower than using a standard property based access, like this:

    while Step do
      assert(Copy(Column['AccountNumber'],1,8)='AW000001');

But the first version, using late-binding of column name, just sounds more natural.

Of course, since it's late-binding, we are not able to let the compiler check at compile time for the column name. If the column name in the source code is wrong, an error will be triggered at runtime only. But it would not be an issue, since it would be the same for the SQL code inserted: it's only executed at runtime (this is one of the benefits of using an ORM, by the way: the ORM will generate correct SQL code for you...).

The default VCL implementation of this late-binding was a bit slow for our purpose.
Since it has to deal with Ole Automation, and because it's fun, we hacked the VCL to provide a lighter and faster version for our custom variant types.

Continue reading

2011-07-01

SynOleDB: OpenSource Unit for direct access to any database via OleDB

That's it, our SynOleDB unit seems alive and running well.

OLE DB (Object Linking and Embedding, Database, sometimes written as OLEDB or OLE-DB) is an API designed by Microsoft for accessing data from a variety of sources in a uniform manner. It was designed as a higher-level replacement for, and successor to, ODBC, extending its feature set to support a wider variety of non-relational databases, such as object databases and spreadsheets that do not necessarily implement SQL.

SynOleDB unit implementation has been made with several points in mind:

  • Tested with SQL Server 2008 R2 and Oracle 11g providers from Microsoft and Oracle; 
  • Ability to be truly Unicode, even with pre-Unicode version of Delphi (like Delphi 7 or 2007); 
  • Could access any local or remote Database, from any version of Delphi, since it doesn't use the DB.pas unit or any related part of the VCL (even the Delphi 7 personal or the Turbo Explorer editions), just for free; 
  • Handle NULL or BLOB content for parameters and results; 
  • Avoid most memory copy or unnecessary allocation: we tried to access the data directly from the retrieved data buffer, just as given from OleDB; 
  • Was therefore designed to achieve the best performance possible: most time is spent in OleDB: the code layer added to the OleDB customer is very thin; 
  • True OOP architecture, to be used with any OleDB provider (allowing custom parameters or such), and even without OleDB (in the future, direct access to any DB client could be used); 
  • Could be safely used in a multi-threaded application/server (with one TOleDBConnection per thread); 
  • Allow parameter bindings of requests, with fast access to any parameter or column name (thanks to TDynArrayHashed);
  • Late binding of column values in Delphi code;
  • Direct JSON content creation, with no temporary data copy nor allocation; 
  • Designed to be used with our mORMot ORM, but could be used stand-alone (a full Delphi 7 client executable is just about 200 KB), or even in any existing Delphi application, thanks to a TQuery-like wrapper.

Continue reading

2011-06-29

Synopse SQLite3 framework 1.14

Our ORM framework has been released as version 1.14.

It's mainly a bug-fix release:

  • Integrated SQLite3 engine updated to latest version 3.7.7.1;
  • Fix several issues about JSON generation layout;
  • Enhanced automated User Interface generation for object on-screen edition;
  • SynPdf unit now handles Bézier curves from TCanvas, and some CMYK functions; also enhanced PDF/A-1compatibility;
  • Some speed enhancements, and new functions for the SynOleDB unit.

Continue reading

2011-06-05

Synopse SQLite3 Framework 1.13

This is a major step for the framework.

Among a lot of new features and bug fixes:

Open Source project, for Delphi 6 up to XE, licensed under a MPL/LGPL/GPL tri-license.

Continue reading

2011-06-02

Custom SQL functions

The SQLite3 engine defines some standard SQL functions, like abs() min() max() or upper().
A complete list is available at http://www.sqlite.org/lang_corefunc.html

One of the greatest SQLite3 feature is the ability to define custom SQL functions in high-level language. In fact, its C API allows to implement new functions which may be called within a SQL query. In other database engine, such functions are usually named UDF (for User Defined Functions).

Our framework allows you to add easily such custom functions, directly from Delphi classes.

Continue reading

BATCH sequences for adding/updating/deleting records

When use the so-called BATCH sequences?

In a standard Client-Server architecture, especially with the common understanding (and most implementations) of a RESTful service, any Add / Update / Delete method call requires a back and forth flow to then from the remote server.

In case of a remote connection via the Internet (or a slow network), you could have some 100 ms of latency: it's just the "ping" timing, i.e. the time spent for your IP packet to go to the server, then back to you.

If you are making a number of such calls (e.g. add 1000 records), you'll have 100*1000 ms = 100 s = 1:40 min just because of this network latency!

The BATCH sequence allows you to regroup those statements into just ONE remote call. Internally, it builds a JSON stream, then post this stream at once to the server. Then the server answers at once, after having performed all the modifications.

Continue reading

TSQLRecordRTree to implement R-Tree virtual tables

An R-Tree is a special index that is designed for doing range queries.

R-Trees are most commonly used in geospatial systems where each entry is a rectangle with minimum and maximum X and Y coordinates. Given a query rectangle, an R-Tree is able to quickly find all entries that are contained within the query rectangle or which overlap the query rectangle.

 This idea is easily extended to three dimensions for use in CAD systems. R-Trees also find use in time-domain range look-ups. For example, suppose a database records the starting and ending times for a large number of events. A R-Tree is able to quickly find all events, for example, that were active at any time during a given time interval, or all events that started during a particular time interval, or all events that both started and ended within a given time interval. And so forth. See http://www.sqlite.org/rtree.html

Since the 2010-06-25 source code repository update, the RTREE extension is compiled by default within all supplied .obj files of the framework.

A dedicated ORM class, named TSQLRecordRTree, is available to create such tables. It inherits from TSQLRecordVirtual, like the other virtual tables types (e.g. TSQLRecordFTS3 or our custom virtual tables).

Continue reading

2011-06-01

Business rules: validate and filter data

According to the n-Tier architecture, data filtering and validation should be implemented in the business logic, not in the User Interface.

If you were used to develop RAD database application using Delphi, you may have to change a bit your habits here. Data filtering and validation should be implemented not in the User Interface, but in pure Delphi code.

Data filtering is a process run on the User entry: for instance, it will trim left or right spaces, make the text uppercase...
Data validating is performed before saving the data to the database: for instance, an email address is checked for consistency, a field value to be unique...

Some try to implement this using an external scripting engine, in a procedure/event mode. Back to the 80th...
In our ORM framework, filtering and validation can be performed by creating some Delphi classes, which may be used on both Server and Client side.

Continue reading

2011-05-14

Virtual Tables in the SQLite3 framework

The SQlite3 engine has ability to create Virtual Tables from code. From the perspective of an SQL statement, the virtual table object looks like any other table or view. But behind the scenes, queries from and updates to a virtual table invoke callback methods on the virtual table object instead of reading and writing to the database file.

The virtual table mechanism allows an application to publish interfaces that are accessible from SQL statements as if they were tables. SQL statements can in general do anything to a virtual table that they can do to a real table, with the following exceptions:
- One cannot create a trigger on a virtual table.
- One cannot create additional indices on a virtual table. (Virtual tables can have indices but that must be built into the virtual table implementation. Indices cannot be added separately using CREATE INDEX statements.)
- One cannot run ALTER TABLE ... ADD COLUMN commands against a virtual table.
- Particular virtual table implementations might impose additional constraints. For example, some virtual implementations might provide read-only tables. Or some virtual table implementations might allow INSERT or DELETE but not UPDATE. Or some virtual table implementations might limit the kinds of UPDATEs that can be made.

Example of virtual tables, already included in the SQLite3 engine, are FTS or RTREE tables. A custom virtual table might represent in-memory data structures (like TSQLVirtualTableJSON, TSQLVirtualTableBinary). Or it might represent a view of data on disk that is not in the SQLite3 format (e.g. TSQLVirtualTableLog). Or the application might compute the content of the virtual table on demand.

Thanks to the generic implementation of Virtual Table in SQLite3, you can use such tables in your SQL statement, and even safely execute a SELECT statement with JOIN or custom functions, mixing normal SQLite3 tables and any other Virtual Table.

A dedicated mechanism has been added to the framework, beginning with revision 1.13, in order to easily add such virtual tables with pure Delphi code, just by inheriting some classes.

Continue reading

2011-02-07

SQLite3 Framework updated to 1.12 - including engine 3.7.5

The Synopse SQLite3 Database Framework was just released under version 1.12:

  • internal SQLite3 database engine was updated to version 3.7.5, and SQL functions have been enhanced;
  • now handle prepared SQL statements with a neutral automated syntax;
  • with Delphi 2009/2010/XE, you can define directly Unicode string properties in TSQLRecord (will be stored as UTF-8);
  • include some overloaded methods using Variants for direct property access (e.g. in any grid);
  • SynPdf has now direct bookmarks and links methods, can reuse any existing bitmap, and generate PDF/A-1 files;
  • internal reporting now supports bookmarks and links (with on screen navigation), and better integrates with SynPdf;
  • a lot of bug fixes, new methods and enhancements.

Continue reading

2011-01-22

Synopse Big Table 1.12a

Synopse Big Table is an open source Delphi unit for very fast data storage and access, using key/values pairs, or records organized with fields.

With this 1.12a version, the unit has evolved into a true field-oriented database, with two new classes:
TSynBigTableRecord to store an unlimited number of records with fields;
TSynBigTableMetaData to store any data (pictures, HTML, text) associated with metadata fields.

Both classes handle variable-length storage of integers, floats, currency, text (Unicode or not) with a field name. On-the-fly field adding, integrated indexing and search capabilities.
Data access can be either fast direct access, or via late-binding (i.e. use Record.Field in your Delphi code).

Classic Key/Value storage is always possible via TSynBigTable or TSynBigTableString, but is now faster and safer. A few issues were corrected.

Update: version 1.12b has been published (same download link).
Some issues have been fixed about packing and the two new classes types.

Continue reading

2010-12-21

Synopse Big Table 1.12

Synopse Big Table is an open source Delphi unit for very fast data storage and access, using key/values pairs.
If you just need to save raw data on disk, and retrieve it with an unique ID number or string, this unit could fit your needs.
The unit has been deeply rewritten for the new version 1.12.

Main enhancements are great speed improving, less disk space use, new dedicated methods (and direct update of any record content).

Continue reading

2010-12-18

SQL parameters can now be prepared "on the fly"

Up to now, most SQL statements were parsed, then prepared before execution.
Only individual TSQLRecord content retrieval was using prepared statements.

For the upcoming version 1.12 of the framework, we added an internal SQL statement cache in the database access.
That is, if a previous SQL statement is run with some parameters, a prepared version, available in cache, is used, and new parameters are bounded to it before the execution by SQLite3.

In some cases, it can speed the SQLite3 process a lot.

Continue reading

2010-12-13

SQLite3 Framework updated to 1.11 - including engine 3.7.4

The Synopse SQLite3 Database Framework was just released under version 1.11:

- internal SQLite3 database engine is updated to version 3.7.4;
- new TSQLRecordMany to handle "has many" and "has many through" relationships;
- new TSQLRecordFTS4 class, to handle the new FTS4 extension module;
- new RANK() function available in SQL statements for ranking FTS3/FTS4;
- introduces new TSQLite3DB, TSQLite3Statement, TSQLite3Blob, TSQLite3Value and TSQLite3FunctionContext types to clarify SQLite3 internal handle usage;
- new sqlite3_busy_timeout and sqlite3_busy_handler low-level functions, with new TSQLDataBase.BusyTimeout property;
- now handles User Defined Functions, via sqlite3_create_function_v2 and corresponding sqlite3_result_* functions;
- new MOD() and SOUNDEX() functions available in SQL statements;
- a lot of code refactoring, speed improvements, numerous fixes, new methods.

Continue reading

2010-10-28

"has many" and "has many through" relationships

Extracted from wikipedia, here is a definition of 'many to many' relationships in regular database management:

In systems analysis, a many-to-many relationship is a type of cardinality that refers to the relationship between two entities (see also Entity-Relationship Model) A and B in which A may contain a parent row for which there are many children in B and vice versa. For instance, think of A as Authors, and B as Books. An Author can write several Books, and a Book can be written by several Authors. Because most database management systems only support one-to-many relationships, it is necessary to implement such relationships physically via a third and fourth junction table, say, AB with two one-to-many relationships A -> AB and B -> AB. In this case the logical primary key for AB is formed from the two foreign keys (i.e. copies of the primary keys of A and B).

In our SQLite3 framework, we just created a dedicated class for handling such "many to many" relationships.

Continue reading

- page 5 of 6 -