You are not logged in.
Hi erick,
His your mORMot book still on schedule ?
Arrays are not allowed in paths.
Try this:
R := doc.routes._(0).duration;
Routes is an array, which item (position) of the array are you targeting ?
Add my voice to the people who want to see the code behind those videos ! Would be greatly appreciated warleyalex !
Doesn't VACUUM do this in SQLite ?
Can't wait to get your book on mORMot erick !
OK thanks, I still have to convert my way of thinking to the ORM way !
Hi,
Is it possible to set a default value when defining properties in TSQLRecord descendants (meaning that if I omit a property in a query, the default value should be used) ?
Or should I use the RDBMS to do it ?
Thanks.
Hi,
When using non nullable types for field definitions, shouldn't the corresponding columns in the tables have the "NOT NULL" constraint by default ? Also, shouldn't the ID column always be "NOT NULL" ?
Could you use a symbolic link (mklink /d) ?
Hi,
Is it possible to use HttpGet from SynCrtSock to retrieve the content of a web page that has been _redirected_ ? If yes, how ? :-p
For ex. this code will return an empty string:
HttpGet('http://www.betexplorer.com/soccer/france/ligue-1-2015-2016/');
because the URL is redirected to 'http://www.betexplorer.com/soccer/france/'. I'd like to retrieve the content of the final redirection...
We need a "Thumbs Up" button on this forum :-)
Thanks !
Hi Arnaud,
I want to use your wrapper only because I'm trying to convert some old project from another set of SQLite components (Aducom) to Synopse and the project uses a TQuery component already.
I get the expected behavior if I comment out the line of code generating the exception in SynDBSQLite3.pas.
Now as I'm continuing to play with the wrapper, I get a problem with Date/DateTime fields:
SQL.Text := 'INSERT OR IGNORE INTO Test3 VALUES (:key, :value);';
ParamByName('key').AsString := Format('Clé %d', [i1]);
ParamByName('value').AsDateTime := Now;
ExecSQL;Using some external tool to check my DB, I see the values are stored in this format: "2015-07-07T16:17:51".
The problem is when I want to read the values again using the wrapper:
SQL.Text := 'SELECT * FROM Test3;';
Open;
while not Eof do begin
if FieldByName('value').AsDateTime > Now then // ***
// ...
Next;
end;*** I'm getting the following error:
Project ... raised exception class EVariantTypeCastError with message 'Could not convert variant of type (UnicodeString) into type (Double)'
Also while I'm here, why do you use "65535" as the "True" value for storing booleans in SQLite DBs ?
Thanks !
Hi ab,
I'm playing with your TQuery wrapper to query a local SQLite3 file but I get this exception when using TQuery.First procedure for the second time; that is it seems to works once, then on the second run of the code, the exception raises.
Here a simple project demonstrating my problem :-\
unit fmTest;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, Forms, StdCtrls,
SynCommons, SynDB, SynDBSQLite3, SynSQLite3, SynSQLite3Static;
type
TfrmTest = class(TForm)
btnTest: TButton;
mmoLog: TMemo;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure btnTestClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
const
DB_FILENAME = 'Tests.sqlite';
var
frmTest: TfrmTest;
Props: TSQLDBConnectionProperties;
Conn: TSQLDBConnection;
Qry: TQuery;
implementation
{$R *.dfm}
procedure TfrmTest.btnTestClick(Sender: TObject);
var
Timer: TPrecisionTimer;
s: string;
i1, iTrue, iFalse: Integer;
begin
mmoLog.Clear;
with Qry do begin
Close;
SQL.Text := 'DELETE FROM Test;';
ExecSQL;
Timer.Start;
SQL.Text := 'INSERT OR IGNORE INTO Test VALUES (:Key, :Value);';
Conn.StartTransaction;
for i1 := 0 to 999 do begin
ParamByName('Key').AsString := Format('Clé %d', [i1]);
ParamByName('Value').AsBoolean := (Random(2) = 1);
ExecSQL;
end;
Conn.Commit;
SQL.Text := 'SELECT * FROM Test;';
Open;
iTrue := 0;
iFalse := 0;
while not Eof do begin
if Fields[1].AsBoolean then
Inc(iTrue)
else
Inc(iFalse);
Next;
end;
Timer.Stop;
mmoLog.Lines.BeginUpdate;
SQL.Text := 'SELECT * FROM test;';
Open;
(* while not Eof do begin
Next;
// mmoLog.Lines.Add(FieldByName('Key').AsString);
end; *)
First; // <<<<<<<<<<<< Happens here, but also happens if I comment this line out, so the problem could be on the next line of code !
mmoLog.Lines.Add(Fields[0].AsString);
mmoLog.Lines.EndUpdate;
s := Format('%d valeurs à True, %d valeurs à False', [iTrue, iFalse]);
mmoLog.Lines.Add(s);
s := Format('Terminé en %s', [Timer.Time]);
mmoLog.Lines.Add(s);
end;
end;
procedure TfrmTest.FormCreate(Sender: TObject);
begin
Randomize;
Props := TSQLDBSQLite3ConnectionProperties.Create(StringToUTF8(DB_FILENAME), '', '', '');
Conn := Props.NewConnection;
Conn.Connect;
Qry := TQuery.Create(Conn);
with Qry do begin
SQL.Text := 'PRAGMA synchronous = OFF;';
ExecSQL;
end;
end;
procedure TfrmTest.FormDestroy(Sender: TObject);
begin
Qry.Free;
Props.Free;
end;
end.Am I doing something wrong ? (probably :-p)
Also, not sure about when to use the TQuery.Close procedure, is it required after each query is finished or only certain ones ? Sometimes the debugger will complain about a missing Close (exception 'TQuery.Prepare called with no previous Close'), sometimes it will run smoothly...
You're one of the best Delphi advocate I've read in the last few years ! That's the kind of demonstration that give me the desire to continue working with Delphi, and could give me new ideas too, or ideas I would not have thought of developing with Delphi... What are Embarcadero doing ? We and they need more people like you !
:-) <- that is the face I'm doing now. I do it every time I come to check your work. I'm always amazed.
BTW, I'm totally fine with the default behavior as it perfectly matches my usage.
Hi ab,
I'm confused with the per-value or per-reference access to TDocVariant; here is some code I tested:
var
o, oSeasons, oSeason: Variant;
s: string;
i1: Integer;
begin
s := '{"Url": "argentina", "Seasons":[{"Name": "2011/2012", "Url": "2011-2012", "Competitions": [{"Name": "Ligue1",';
s := s + '"Url": "ligue-1"}, {"Name": "Ligue2", "Url": "ligue-2"}]}, {"Name": "2010/2011", "Url": "2010-2011",';
s := s + ' "Competitions": [{"Name": "Ligue1", "Url": "ligue-1"}, {"Name": "Ligue2", "Url": "ligue-2"}]}]}';
o := _Json(s);
oSeasons := o.Seasons;
for i1 := 0 to oSeasons._Count - 1 do begin
oSeason := oSeasons._(i1);
oSeason.Name := 'CHANGED !'; // (1)
oSeason.Extra := 'blabla'; // (2)
end;
AddToLog(o); // Will simply output the content of "o" in a TMemo.
end;But unexpectedly (for me !) the changes made in (1) and (2) in TDocVariant "oSeason" appear in TDocVariant "o" ((See below)) !? Did I miss or misunderstand something ? Isn't oSeason supposed to be "copied-by-value" by default ?
{"Url":"argentina","Seasons":[{"Name":"CHANGED !","Url":"2011-2012","Competitions":[{"Name":"Ligue1","Url":"ligue-1"},{"Name":"Ligue2","Url":"ligue-2"}],"Extra":"blabla"},{"Name":"CHANGED !","Url":"2010-2011","Competitions":[{"Name":"Ligue1","Url":"ligue-1"},{"Name":"Ligue2","Url":"ligue-2"}],"Extra":"blabla"}]}
I suppose you have to be careful when deleting an item from an object, as items in objects are not ordered (contrary to items in arrays) ?
I haven't tested yet but if this is possible...
V='["root",{"name":"Jim","year":1972},3.1415]';
V._(1).Delete(0);...then it could result in...
V='["root",{"year":1972},3.1415]' or V='["root",{"name":"Jim"},3.1415]' ?
Great ! Thanks, for this and everything else.
Coming from superobject, I'm used to do things like...
var
a, o: ISuperObject;
// ...
begin
a := SA([]);
o := SO();
// Do some stuff with o
a[''] := o; // Add object o to array a
// do more stuff
end;I know I can do it with TDocVariant by transtyping:
var
a, o: Variant;
// ...
begin
a := _Arr([]);
o := _Obj([]);
// Do some stuff with o
TDocVariantData(a).AddItem(o); // OK
// do more stuff
end;but is there a syntax similar to the one of SO ? Something like:
// a := a + o;If not, it doesn't matter, I just that I don't want to miss some easier way to write it if it exists.
Formidable !
Need to try this ASAP, may replace SO in my current personal project :-)
Looks like a great alternative to SuperObject ???
Taken from your own examples:
V1 := _Obj(['name','John','year',1972]);
V2 := _Obj(['name','John','doc',_Obj(['one',1,'two',2.5])]);
// ...
writeln('name=',V2.name,' doc.one=',V2.doc.one,' doc.two=',doc.two);
// ...
if V1.Exists('year') then
writeln(V1.year);Is it possible to call...
if V2.doc.Exists('one') then ...and so on ?
Also, how do you deal with names containing a dot ? Ex:
V2 := _Obj(['name','John','doc.part1',_Obj(['one',1,'two',2.5])]);
// writeln('name=',V2.name,' doc.part1.one=',V2."doc.part1".one,' doc.two=',V2."doc.part1".two); ???
// if V2."doc.part1".Exists('one') then... ???Ok, forget about it, Sample 02 is working fine so I guess it's a problem in Sample 01, not in my installation...
Hi,
I downloaded your framework, I'm really impressed by your technical level, having read a few messages here, and I'm also ashamed by my own incompetency level... 'cause, first thing I did after unzipping the main archive was to try the first demo, and got a "Project Project01.exe raised an exception class EAbstractError with message 'Abstract Error'..." when trying to add my first message to the DB :-\
Did I miss something, somewhere ?
Thanks.