mORMot and Open Source friends
Check-in [f633312bdc]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:TSQLRequest.Execute(JSON: TStream) now allows field names at least, even with no data (as expected by TSQLRestClientURI.UpdateFromServer)
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: f633312bdc0ae8e2d81e23976ae38ea7640e81cd
User & Date: G018869 2012-03-19 13:19:17
Context
2012-03-21
09:08
  • TSQLRestServer.ServiceRegister(aClient: TSQLRest...) for a remote access
  • added function IsNotAjaxJSON() function - formerly internal IsExpanded()
  • fixed potential issue of misleaded client side remote content
check-in: 95d09e80f0 user: G018869 tags: trunk
2012-03-19
13:19
TSQLRequest.Execute(JSON: TStream) now allows field names at least, even with no data (as expected by TSQLRestClientURI.UpdateFromServer) check-in: f633312bdc user: G018869 tags: trunk
10:21
  • fixed VACUUM failure if there are one or more active SQL statements
  • fixed potential GPF in TDynArrayHashed.ReHash after TDynArray.Clear call
check-in: f81f788718 user: G018869 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to SQLite3/SQLite3.pas.

966
967
968
969
970
971
972



973
974
975
976
977
978
979
980
981
  if (self=nil) or (cardinal(TableModelIndex)>=cardinal(length(Model.TableProps))) then
    exit;
  with Model.TableProps[TableModelIndex] do
    SQL := FormatUTF8('SELECT % FROM % WHERE RowID=:(%):;',
      [SQLTableSimpleFields[true,false],SQLTableName,ID]);
  result := EngineList(SQL,true); // ForceAJAX=true -> '[{...}]'#10
  if result<>'' then



    // list '[{...}]'#10 -> object '{...}'
    result := copy(result,2,length(result)-3);
end;

function TSQLRestServerDB.EngineRetrieveBlob(Table: TSQLRecordClass;
  aID: integer; BlobField: PPropInfo; out BlobData: TSQLRawBlob): boolean;
var SQL: RawUTF8;
    Req: PSQLRequest;
begin






>
>
>
|
|







966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
  if (self=nil) or (cardinal(TableModelIndex)>=cardinal(length(Model.TableProps))) then
    exit;
  with Model.TableProps[TableModelIndex] do
    SQL := FormatUTF8('SELECT % FROM % WHERE RowID=:(%):;',
      [SQLTableSimpleFields[true,false],SQLTableName,ID]);
  result := EngineList(SQL,true); // ForceAJAX=true -> '[{...}]'#10
  if result<>'' then
    if IsExpanded(pointer(result)) then
      // '{"FieldCount":2,"Values":["ID","FirstName"]}'#$A -> ID not found
      result := '' else
      // list '[{...}]'#10 -> object '{...}'
      result := copy(result,2,length(result)-3);
end;

function TSQLRestServerDB.EngineRetrieveBlob(Table: TSQLRecordClass;
  aID: integer; BlobField: PPropInfo; out BlobData: TSQLRawBlob): boolean;
var SQL: RawUTF8;
    Req: PSQLRequest;
begin

Changes to SQLite3/SQLite3Commons.pas.

1255
1256
1257
1258
1259
1260
1261




1262
1263
1264
1265
1266
1267
1268
// - if RowID is set, a RowID column will be added within the returned content
function GetJSONObjectAsSQL(JSON: RawUTF8; Update, InlinedParams: boolean;
  RowID: Integer=0): RawUTF8; overload;

/// get the FIRST field value of the FIRST row, from a JSON content
// - e.g. usefull to get an ID without converting a JSON content into a TSQLTableJSON
function UnJSONFirstField(var P: PUTF8Char): RawUTF8;





/// get the number of rows stored in the not-expanded JSON content
function GetRowCountNotExpanded(P: PUTF8Char; FieldCount: integer; var RowCount: integer): PUTF8Char;

/// go to the end of a field name in a JSON '"FieldName":Value' pair
// - returns nil if P was not formatted as expected
// - returns the position of Value






>
>
>
>







1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
// - if RowID is set, a RowID column will be added within the returned content
function GetJSONObjectAsSQL(JSON: RawUTF8; Update, InlinedParams: boolean;
  RowID: Integer=0): RawUTF8; overload;

/// get the FIRST field value of the FIRST row, from a JSON content
// - e.g. usefull to get an ID without converting a JSON content into a TSQLTableJSON
function UnJSONFirstField(var P: PUTF8Char): RawUTF8;

/// returns TRUE if the JSON content is in expanded format
// - i.e. as '{"FieldCount":3,"Values":["ID","FirstName","LastName",...']} 
function IsExpanded(P: PUTF8Char): Boolean;

/// get the number of rows stored in the not-expanded JSON content
function GetRowCountNotExpanded(P: PUTF8Char; FieldCount: integer; var RowCount: integer): PUTF8Char;

/// go to the end of a field name in a JSON '"FieldName":Value' pair
// - returns nil if P was not formatted as expected
// - returns the position of Value

Changes to SynSQLite3.pas.

107
108
109
110
111
112
113


114
115
116
117
118
119
120
....
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
....
4048
4049
4050
4051
4052
4053
4054

4055







4056
4057
4058
4059
4060
4061
4062
  - reintroduce TSQLDataBaseSQLFunction.Create() constructor, and added some
    TSQLDataBase.RegisterSQLFunction() overloaded methods
  - fixed issue in TSQLRequest.Reset() which was triggered an error about the
    latest statement execution
  - fixed potential issue after TSQLStatementCached.ReleaseAllDBStatements
  - fixed rounding issue when exporting DOUBLE columns into JSON
  - fixed issue of unraised exception in TSQLRequest.PrepareNext


  - renamed ESQLException into ESQLite3Exception
  - engine is now compiled including tracing within the FTS3 extension - added
    sqlite3_trace() function prototype to register your own tracing callback

    Todo:
    - port to systems other than Delphi+Win32 (use external DLL?)
}
................................................................................
    Close; // always release statement
  end;
end;

function TSQLRequest.Execute(aDB: TSQLite3DB; const aSQL: RawUTF8; JSON: TStream;
  Expand: boolean=false): PtrInt;
// expand=true: [ {"col1":val11,"col2":"val12"},{"col1":val21,... ]
// expand=false: { "FieldCount":1,"Values":["col1","col2",val11,"val12",val21,..] }
var i: integer;
    W: TJSONWriter;
begin
  result := 0;
  W := TJSONWriter.Create(JSON,Expand,false);
  try
    // prepare the SQL request
................................................................................
        FieldsToJSON(W);
        W.Add(',');
      end;
      SQLITE_DONE:
        break;
      end;
    until false;

    // we want the field names at least, even with no data: we allow RowCount=0







    W.CancelLastComma; // cancel last ','
    W.Add(']');
    if not Expand then
      W.Add('}');
    W.Add(#10);
    W.Flush;
  finally






>
>







 







|







 







>
|
>
>
>
>
>
>
>







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
....
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
....
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
  - reintroduce TSQLDataBaseSQLFunction.Create() constructor, and added some
    TSQLDataBase.RegisterSQLFunction() overloaded methods
  - fixed issue in TSQLRequest.Reset() which was triggered an error about the
    latest statement execution
  - fixed potential issue after TSQLStatementCached.ReleaseAllDBStatements
  - fixed rounding issue when exporting DOUBLE columns into JSON
  - fixed issue of unraised exception in TSQLRequest.PrepareNext
  - TSQLRequest.Execute(JSON: TStream) now allows field names at least, even
    with no data (as expected by TSQLRestClientURI.UpdateFromServer)
  - renamed ESQLException into ESQLite3Exception
  - engine is now compiled including tracing within the FTS3 extension - added
    sqlite3_trace() function prototype to register your own tracing callback

    Todo:
    - port to systems other than Delphi+Win32 (use external DLL?)
}
................................................................................
    Close; // always release statement
  end;
end;

function TSQLRequest.Execute(aDB: TSQLite3DB; const aSQL: RawUTF8; JSON: TStream;
  Expand: boolean=false): PtrInt;
// expand=true: [ {"col1":val11,"col2":"val12"},{"col1":val21,... ]
// expand=false: { "FieldCount":2,"Values":["col1","col2",val11,"val12",val21,..] }
var i: integer;
    W: TJSONWriter;
begin
  result := 0;
  W := TJSONWriter.Create(JSON,Expand,false);
  try
    // prepare the SQL request
................................................................................
        FieldsToJSON(W);
        W.Add(',');
      end;
      SQLITE_DONE:
        break;
      end;
    until false;
    if (result=0) and W.Expand then begin
      // we want the field names at least, even with no data: we allow RowCount=0
      Expand := false; //  {"FieldCount":2,"Values":["col1","col2"]}
      W.Expand := false;
      W.CancelAll;
      for i := 0 to FieldCount-1 do
        W.ColNames[i] := sqlite3_column_name(Request,i);
      W.AddColumns;
    end;
    W.CancelLastComma; // cancel last ','
    W.Add(']');
    if not Expand then
      W.Add('}');
    W.Add(#10);
    W.Flush;
  finally