Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Comment: | {2947} ensure JSONGetID() will return false if ID<=0 e.g. if {"ID":null,... is supplied as input |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
8ac7d70abc09c40f1b9e7ee7e15adb95 |
User & Date: | ab 2016-09-13 10:08:15 |
2016-09-13
| ||
10:09 | {2948} small refactoring with no functional change check-in: e5d8b046bd user: ab tags: trunk | |
10:08 | {2947} ensure JSONGetID() will return false if ID<=0 e.g. if {"ID":null,... is supplied as input check-in: 8ac7d70abc user: ab tags: trunk | |
08:47 | {2946} fixed [33568686fd] - certainly due to a cafeine low level check-in: 60826e6664 user: ab tags: trunk | |
Changes to SQLite3/mORMot.pas.
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
.....
26739
26740
26741
26742
26743
26744
26745
26746
26747
26748
26749
26750
26751
26752
26753
26754
26755
26756
26757
26758
26759
26760
26761
26762
26763
26764
26765
26766
26767
26768
26769
26770
26771
26772
26773
26774
26775
26776
26777
26778
26779
26780
|
// "Name":Value pairs, as generated by TSQLRecord.GetJSONValues(W) function JSONGetObject(var P: PUTF8Char; ExtractID: PID; var EndOfObject: AnsiChar; KeepIDField: boolean): RawUTF8; /// retrieve the ID/RowID field of a JSON object // - this function expects this "ID" property to be the FIRST in the // "Name":Value pairs, as generated by TSQLRecord.GetJSONValues(W) // - returns TRUE if ID/RowID has been found, and set ID with the value function JSONGetID(P: PUTF8Char; out ID: TID): Boolean; /// fill a TSQLRawBlob from TEXT-encoded blob data // - blob data can be encoded as SQLite3 BLOB literals (X'53514C697465' e.g.) or // or Base-64 encoded content ('\uFFF0base64encodedbinary') or plain TEXT function BlobToTSQLRawBlob(P: PUTF8Char): TSQLRawBlob; overload; ................................................................................ end; function StartWithQuotedID(P: PUTF8Char; out ID: TID): boolean; begin if PCardinal(P)^ and $ffffdfdf= ord('I')+ord('D')shl 8+ord('"')shl 16+ord(':')shl 24 then begin SetID(P+4,ID); result := true; exit; end else if (PCardinalArray(P)^[0] and $dfdfdfdf= ord('R')+ord('O')shl 8+ord('W')shl 16+ord('I')shl 24) and (PCardinalArray(P)^[1] and $ffffdf= ord('D')+ord('"')shl 8+ord(':')shl 16) then begin SetID(P+7,ID); result := true; exit; end; ID := 0; result := false; end; function StartWithID(P: PUTF8Char; out ID: TID): boolean; begin if PCardinal(P)^ and $ffdfdf= ord('I')+ord('D')shl 8+ord(':')shl 16 then begin SetID(P+3,ID); result := true; exit; end else if (PCardinalArray(P)^[0] and $dfdfdfdf= ord('R')+ord('O')shl 8+ord('W')shl 16+ord('I')shl 24) and (PCardinalArray(P)^[1] and $ffdf=ord('D')+ord(':')shl 8) then begin SetID(P+6,ID); result := true; exit; end; ID := 0; result := false; end; function JSONGetID(P: PUTF8Char; out ID: TID): Boolean; |
|
|
|
|
|
|
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
.....
26739
26740
26741
26742
26743
26744
26745
26746
26747
26748
26749
26750
26751
26752
26753
26754
26755
26756
26757
26758
26759
26760
26761
26762
26763
26764
26765
26766
26767
26768
26769
26770
26771
26772
26773
26774
26775
26776
26777
26778
26779
26780
|
// "Name":Value pairs, as generated by TSQLRecord.GetJSONValues(W) function JSONGetObject(var P: PUTF8Char; ExtractID: PID; var EndOfObject: AnsiChar; KeepIDField: boolean): RawUTF8; /// retrieve the ID/RowID field of a JSON object // - this function expects this "ID" property to be the FIRST in the // "Name":Value pairs, as generated by TSQLRecord.GetJSONValues(W) // - returns TRUE if a ID/RowID>0 has been found, and set ID with the value function JSONGetID(P: PUTF8Char; out ID: TID): Boolean; /// fill a TSQLRawBlob from TEXT-encoded blob data // - blob data can be encoded as SQLite3 BLOB literals (X'53514C697465' e.g.) or // or Base-64 encoded content ('\uFFF0base64encodedbinary') or plain TEXT function BlobToTSQLRawBlob(P: PUTF8Char): TSQLRawBlob; overload; ................................................................................ end; function StartWithQuotedID(P: PUTF8Char; out ID: TID): boolean; begin if PCardinal(P)^ and $ffffdfdf= ord('I')+ord('D')shl 8+ord('"')shl 16+ord(':')shl 24 then begin SetID(P+4,ID); result := ID>0; exit; end else if (PCardinalArray(P)^[0] and $dfdfdfdf= ord('R')+ord('O')shl 8+ord('W')shl 16+ord('I')shl 24) and (PCardinalArray(P)^[1] and $ffffdf= ord('D')+ord('"')shl 8+ord(':')shl 16) then begin SetID(P+7,ID); result := ID>0; exit; end; ID := 0; result := false; end; function StartWithID(P: PUTF8Char; out ID: TID): boolean; begin if PCardinal(P)^ and $ffdfdf= ord('I')+ord('D')shl 8+ord(':')shl 16 then begin SetID(P+3,ID); result := ID>0; exit; end else if (PCardinalArray(P)^[0] and $dfdfdfdf= ord('R')+ord('O')shl 8+ord('W')shl 16+ord('I')shl 24) and (PCardinalArray(P)^[1] and $ffdf=ord('D')+ord(':')shl 8) then begin SetID(P+6,ID); result := ID>0; exit; end; ID := 0; result := false; end; function JSONGetID(P: PUTF8Char; out ID: TID): Boolean; |
Changes to SQLite3/mORMotDB.pas.
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
....
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
|
const SentData: RawUTF8): TID; begin if (TableModelIndex<0) or (fModel.Tables[TableModelIndex]<>fStoredClass) then result := 0 else // avoid GPF if fBatchMethod<>mNone then if fBatchMethod<>mPOST then result := 0 else begin JSONGetID(pointer(SentData),result); if result=0 then result := EngineLockedNextID else if result>fEngineLockedMaxID then fEngineLockedMaxID := result; InternalBatchAdd(SentData,result); end else begin result := ExecuteFromJSON(SentData,soInsert,0); // UpdatedID=0 -> insert with EngineLockedNextID ................................................................................ F: integer; Query: ISQLDBStatement; begin result := 0; StorageLock(false,'ExecuteFromJson'); // avoid race condition against max(ID) try case Occasion of soInsert: begin JSONGetID(pointer(SentData),InsertedID); if InsertedID=0 then // no specified "ID":... field value -> compute next InsertedID := EngineLockedNextID else if InsertedID>fEngineLockedMaxID then fEngineLockedMaxID := InsertedID; end; soUpdate: if UpdatedID<>0 then InsertedID := 0 else raise ESQLDBException.CreateUTF8('%.ExecuteFromJSON(%,soUpdate,UpdatedID=%)', [self,StoredClass,UpdatedID]); else raise ESQLDBException.CreateUTF8('%.ExecuteFromJSON(%,Occasion=%)?', [self,StoredClass,ToText(Occasion)^]); |
|
<
|
|
|
<
|
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
....
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
|
const SentData: RawUTF8): TID; begin if (TableModelIndex<0) or (fModel.Tables[TableModelIndex]<>fStoredClass) then result := 0 else // avoid GPF if fBatchMethod<>mNone then if fBatchMethod<>mPOST then result := 0 else begin if not JSONGetID(pointer(SentData),result) then result := EngineLockedNextID else if result>fEngineLockedMaxID then fEngineLockedMaxID := result; InternalBatchAdd(SentData,result); end else begin result := ExecuteFromJSON(SentData,soInsert,0); // UpdatedID=0 -> insert with EngineLockedNextID ................................................................................ F: integer; Query: ISQLDBStatement; begin result := 0; StorageLock(false,'ExecuteFromJson'); // avoid race condition against max(ID) try case Occasion of soInsert: if not JSONGetID(pointer(SentData),InsertedID) then // no specified "ID":... field value -> compute next InsertedID := EngineLockedNextID else if InsertedID>fEngineLockedMaxID then fEngineLockedMaxID := InsertedID; soUpdate: if UpdatedID<>0 then InsertedID := 0 else raise ESQLDBException.CreateUTF8('%.ExecuteFromJSON(%,soUpdate,UpdatedID=%)', [self,StoredClass,UpdatedID]); else raise ESQLDBException.CreateUTF8('%.ExecuteFromJSON(%,Occasion=%)?', [self,StoredClass,ToText(Occasion)^]); |
Changes to SynSelfTests.pas.
9492 9493 9494 9495 9496 9497 9498 9499 9500 9501 9502 9503 9504 9505 9506 |
begin
if Pos('TSQLite3Library',Owner.CustomVersions)=0 then
Owner.CustomVersions := Owner.CustomVersions+#13#10+
string(sqlite3.ClassName)+' '+string(sqlite3.Version);
Check(JSONGetID('{"id":123}',id) and (id=123));
Check(JSONGetID('{"rowid":1234}',id) and (id=1234));
Check(JSONGetID(' { "id": 123}',id) and (id=123));
Check(JSONGetID(' { "rowid": 1234}',id) and (id=1234));
Check(not JSONGetID('{"ide":123}',id));
Check(not JSONGetID('{"rowide":1234}',id));
Check(not JSONGetID('{"as":123}',id));
Check(not JSONGetID('{"s":1234}',id));
Check(not JSONGetID('"ide":123}',id));
Check(not JSONGetID('{ rowide":1234}',id));
if ClassType=TTestMemoryBased then
|
| > > > > |
9492 9493 9494 9495 9496 9497 9498 9499 9500 9501 9502 9503 9504 9505 9506 9507 9508 9509 9510 |
begin if Pos('TSQLite3Library',Owner.CustomVersions)=0 then Owner.CustomVersions := Owner.CustomVersions+#13#10+ string(sqlite3.ClassName)+' '+string(sqlite3.Version); Check(JSONGetID('{"id":123}',id) and (id=123)); Check(JSONGetID('{"rowid":1234}',id) and (id=1234)); Check(JSONGetID(' { "id": 123}',id) and (id=123)); Check(JSONGetID(' { "ROWID": 1234}',id) and (id=1234)); Check(not JSONGetID('{"id":0}',id)); Check(not JSONGetID('{"id":-10}',id)); Check(not JSONGetID('{"id":null}',id)); Check(not JSONGetID('{"ROWID":null}',id)); Check(not JSONGetID('{"ide":123}',id)); Check(not JSONGetID('{"rowide":1234}',id)); Check(not JSONGetID('{"as":123}',id)); Check(not JSONGetID('{"s":1234}',id)); Check(not JSONGetID('"ide":123}',id)); Check(not JSONGetID('{ rowide":1234}',id)); if ClassType=TTestMemoryBased then |
Changes to SynopseCommit.inc.
1 |
'1.18.2946'
|
| |
1 |
'1.18.2947'
|