You are not logged in.
Pages: 1
The Delphi language (aka Object Pascal) provided Runtime Type Information (RTTI) more than a decade ago. In short, Runtime Type Information is information about an object's data type that is set into memory at run-time. The RTTI support in Delphi has been added first and foremost to allow the design-time environment to do its job, but developers can also take advantage of it to achieve certain code simplifications. The Synopse SQLite3 Database Framework makes huge use of RTTI, from the database level to the User Interface. Therefore, the resulting program has the advantages of very fast development (Rails-like), but with the robustness of strong typing, and the speed of one of the best compiler available.
In short, it allows the software logic to be extracted from the code itself. Here are the places where this technology was used:
- All database structures are set in the code by normal classes definition, and most of the needed SQL code is created on the fly by the framework, before calling the SQLite3 database engine, resulting in a true Object-relational mapping (ORM) framework;
- All User Interface is generated by the code, by using some simple data structures, relying on enumerations (see next paragraph);
- Most of the text displayed on the screen does rely on RTTI, thanks to the Camel approach (see below), ready to be translated into local languages;
- All internal Event process (such as Button press) relies on enumerations RTTI;
- Options and program parameters are using RTTI for data persistency and screen display (e.g. the Settings window of your program can be created by pure code): adding an option is a matter of a few code lines.
In Delphi, enumeration types or Enum provides a way of to define a list of values. The values have no inherent meaning, and their ordinality follows the sequence in which the identifiers are listed. These values are written once in the code, then used everywhere in the program, even for User Interface generation.
For example, some toolbar actions can be defined with:
type
/// Worklist toolbar actions
TPeopleAction = (
paCreateNew, paDelete, paEdit, paQuit);
Then this TPeopleAction enumerate type is used to create the User Interface ribbon of the Worklist window, just by creating an array of set of this kind:
BarEdit: array[0..1] of set of TPeopleAction = (
[paCreateNew, paDelete, paEdit],
[paQuit] );
The caption of the buttons to be displayed on the screen is then extracted by the framework using "Camel Case": the second button, defined by the paCreateNew identifier in the source code, is displayed as "Create new" on the screen, and this "Create new" is used for direct i18n of the software. For further information about "Camel Case" and its usage in Object Pascal, Java, Dot Net, Python see CamelCase.
Advantages of the RTTI can therefore by sum up:
- Software maintenability, since the whole program logic is code-based, and the User Interface is created from it. It therefore avoid RAD (Rapid Application Development) abuse, which mix the User Interface with data logic, and could lead into "write fast, try to maintain" scenarios;
- Enhanced code security, thanks to Object Pascal strong typing;
- Direct database access from the language object model, without the need of writing SQL or use of a MVC framework;
- User Interface coherency, since most screen are created on the fly;
- Easy i18n of the software, without additional components or systems.
Offline
Is there anyway that RTTI can be built into the TSQLRecord class so that it is easy to extract Field Types and Field Values? (Perhaps it is and I failed to see it). For example, it would be nice to be able to pass a field index and get field value in return.
Offline
See FieldIndex and FieldProp methods of TSQLRecord.
To loop through all fields, see the FieldIndex method implementation: use a loop with P: PPropInfo then P := P^.Next.
Then use the PPropInfo pointer to get all types and values, as expected. For example, you have GetValue GetOrdValue GetInt64Value GetExtendedValue GetLongStrValue methods.
Since version 1.11, you can use the TSQLRecordProperties class to retrieve all RTTI easily, for a given TSQLRecordClass. I'll make visible the PropsCacheGet function for the version 1.12.
Thanks for your interest!
Offline
Thanks - This is great. I extended my TSQLRecord class with two methods GetFieldValue and SetFieldValue, which simplifies my life a lot when I set and receive values from a data grid that I create on the fly.
Offline
That's it.
As I wrote above, the PropsCacheGet function has been made public.
I've also added some methods, which could be useful in case of a Grid usage:
- new TPropInfo.SetVariant/GetVariant methods
- new GetFieldValue/SetFieldValue and GetFieldVariant/SetFieldVariant methods for TSQLRecord
Those methods accept a property name as parameter, and allow access to all properties of a TSQLRecord instance.
Offline
Hi, when compiling the version e9cafa3892879d29 this error occurs:
"endeclared identifier : TSQLCache"
in class :
TSQLDataBase = class
private
fDB: TSQLite3DB;
fFileName: TFileName;
fTransactionActive: boolean;
fLock: TRTLCriticalSection;
/// if not nil, cache is used - see UseCache property
fCache: TSQLCache;
.....
Offline
You didn't refresh all the files.
You need to update SynCommons, SQLite3 and SQLite3Commons units, at least with the latest version available from the source code repository.
Your SQLite3 unit was not updated.
Offline
I went to this link http://synopse.info/fossil/info/0088bc5396 I downloaded zip Archive: Synops OpenSource-0088bc539614c694.zip
Offline
My mistake!
Offline
is there any simple method to get classtype from PPropInfo? instead of using
TSQLRecordClass(P^.PropType^^.ClassType^.ClassType)
thank you.
Offline
i need to know the Class of sftID SQLFieldType
this is what SetRecord() procedure does in the RecordEditForm
sftID:
if aClient<>nil then begin
// ID field (TSQLRecord descendant) is handled by a TComboBox component
// with all possible values of the corresponding TSQLRecord descendant
IDClass := TSQLRecordClass(P^.PropType^^.ClassType^.ClassType);
CB := TComboBox.Create(Scroll);
....
Offline
Pages: 1