mirror of
https://github.com/danieleteti/delphimvcframework.git
synced 2024-11-15 15:55:54 +01:00
Merge branch 'master' of https://github.com/danieleteti/delphimvcframework
This commit is contained in:
commit
de441f63a3
@ -98,7 +98,10 @@ begin
|
||||
case aRQLFIlter.Token of
|
||||
tkEq:
|
||||
begin
|
||||
Result := Format('(%s = %s)', [lDBFieldName, lValue]);
|
||||
if aRQLFIlter.RightValueType = vtNull then
|
||||
Result := Format('(%s IS NULL)', [lDBFieldName])
|
||||
else
|
||||
Result := Format('(%s = %s)', [lDBFieldName, lValue]);
|
||||
end;
|
||||
tkLt:
|
||||
begin
|
||||
@ -118,7 +121,10 @@ begin
|
||||
end;
|
||||
tkNe:
|
||||
begin
|
||||
Result := Format('(%s != %s)', [lDBFieldName, lValue]);
|
||||
if aRQLFIlter.RightValueType = vtNull then
|
||||
Result := Format('(%s IS NOT NULL)', [lDBFieldName])
|
||||
else
|
||||
Result := Format('(%s != %s)', [lDBFieldName, lValue]);
|
||||
end;
|
||||
tkContains:
|
||||
begin
|
||||
|
@ -106,7 +106,10 @@ begin
|
||||
case aRQLFIlter.Token of
|
||||
tkEq:
|
||||
begin
|
||||
Result := Format('(%s = %s)', [lDBFieldName, lValue]);
|
||||
if aRQLFIlter.RightValueType = vtNull then
|
||||
Result := Format('(%s IS NULL)', [lDBFieldName])
|
||||
else
|
||||
Result := Format('(%s = %s)', [lDBFieldName, lValue]);
|
||||
end;
|
||||
tkLt:
|
||||
begin
|
||||
@ -126,7 +129,10 @@ begin
|
||||
end;
|
||||
tkNe:
|
||||
begin
|
||||
Result := Format('(%s != %s)', [lDBFieldName, lValue]);
|
||||
if aRQLFIlter.RightValueType = vtNull then
|
||||
Result := Format('(%s IS NOT NULL)', [lDBFieldName])
|
||||
else
|
||||
Result := Format('(%s != %s)', [lDBFieldName, lValue]);
|
||||
end;
|
||||
tkContains:
|
||||
begin
|
||||
|
@ -97,7 +97,10 @@ begin
|
||||
case aRQLFIlter.Token of
|
||||
tkEq:
|
||||
begin
|
||||
Result := Format('(%s = %s)', [lDBFieldName, lValue]);
|
||||
if aRQLFIlter.RightValueType = vtNull then
|
||||
Result := Format('(%s IS NULL)', [lDBFieldName])
|
||||
else
|
||||
Result := Format('(%s = %s)', [lDBFieldName, lValue]);
|
||||
end;
|
||||
tkLt:
|
||||
begin
|
||||
@ -117,7 +120,10 @@ begin
|
||||
end;
|
||||
tkNe:
|
||||
begin
|
||||
Result := Format('(%s != %s)', [lDBFieldName, lValue]);
|
||||
if aRQLFIlter.RightValueType = vtNull then
|
||||
Result := Format('(%s IS NOT NULL)', [lDBFieldName])
|
||||
else
|
||||
Result := Format('(%s != %s)', [lDBFieldName, lValue]);
|
||||
end;
|
||||
tkContains:
|
||||
begin
|
||||
|
@ -91,7 +91,10 @@ begin
|
||||
case aRQLFIlter.Token of
|
||||
tkEq:
|
||||
begin
|
||||
Result := Format('(%s = %s)', [lDBFieldName, lValue]);
|
||||
if aRQLFIlter.RightValueType = vtNull then
|
||||
Result := Format('(%s IS NULL)', [lDBFieldName])
|
||||
else
|
||||
Result := Format('(%s = %s)', [lDBFieldName, lValue]);
|
||||
end;
|
||||
tkLt:
|
||||
begin
|
||||
@ -111,7 +114,10 @@ begin
|
||||
end;
|
||||
tkNe:
|
||||
begin
|
||||
Result := Format('(%s != %s)', [lDBFieldName, lValue]);
|
||||
if aRQLFIlter.RightValueType = vtNull then
|
||||
Result := Format('(%s IS NOT NULL)', [lDBFieldName])
|
||||
else
|
||||
Result := Format('(%s != %s)', [lDBFieldName, lValue]);
|
||||
end;
|
||||
tkContains:
|
||||
begin
|
||||
|
@ -92,7 +92,10 @@ begin
|
||||
case aRQLFIlter.Token of
|
||||
tkEq:
|
||||
begin
|
||||
Result := Format('(%s = %s)', [lDBFieldName, lValue]);
|
||||
if aRQLFIlter.RightValueType = vtNull then
|
||||
Result := Format('(%s IS NULL)', [lDBFieldName])
|
||||
else
|
||||
Result := Format('(%s = %s)', [lDBFieldName, lValue]);
|
||||
end;
|
||||
tkLt:
|
||||
begin
|
||||
@ -112,7 +115,10 @@ begin
|
||||
end;
|
||||
tkNe:
|
||||
begin
|
||||
Result := Format('(%s != %s)', [lDBFieldName, lValue]);
|
||||
if aRQLFIlter.RightValueType = vtNull then
|
||||
Result := Format('(%s IS NOT NULL)', [lDBFieldName])
|
||||
else
|
||||
Result := Format('(%s != %s)', [lDBFieldName, lValue]);
|
||||
end;
|
||||
tkContains:
|
||||
begin
|
||||
|
@ -78,7 +78,7 @@ type
|
||||
tkOpenPar, tkClosedPar, tkOpenBracket, tkCloseBracket, tkComma, tkSemicolon, tkPlus, tkMinus, tkDblQuote,
|
||||
tkQuote, tkSpace, tkContains, tkIn, tkUnknown);
|
||||
|
||||
TRQLValueType = (vtInteger, vtString, vtBoolean, vtIntegerArray, vtStringArray);
|
||||
TRQLValueType = (vtInteger, vtString, vtBoolean, vtNull, vtIntegerArray, vtStringArray);
|
||||
|
||||
TRQLCustom = class;
|
||||
|
||||
@ -188,6 +188,7 @@ type
|
||||
function MatchFieldNumericValue(out lFieldValue: string): Boolean;
|
||||
function MatchFieldArrayValue(out lFieldValue: string): Boolean;
|
||||
function MatchFieldBooleanValue(out lFieldValue: string): Boolean;
|
||||
function MatchFieldNullValue(out lFieldValue: string): Boolean;
|
||||
function MatchSymbol(const Symbol: Char): Boolean;
|
||||
procedure SaveCurPos;
|
||||
procedure BackToLastPos;
|
||||
@ -618,10 +619,12 @@ begin
|
||||
|
||||
if MatchFieldBooleanValue(lFieldValue) then
|
||||
lValueType := vtBoolean
|
||||
else if MatchFieldNullValue(LFieldValue) then
|
||||
lValueType := vtNull
|
||||
else if MatchFieldNumericValue(lFieldValue) then
|
||||
lValueType := vtInteger
|
||||
else
|
||||
Error('Expected numeric or boolean value');
|
||||
Error('Expected numeric, boolean or null value');
|
||||
end;
|
||||
EatWhiteSpaces;
|
||||
if GetToken <> tkClosedPar then
|
||||
@ -911,6 +914,23 @@ begin
|
||||
Exit(False);
|
||||
end;
|
||||
|
||||
function TRQL2SQL.MatchFieldNullValue(out lFieldValue: string): Boolean;
|
||||
var
|
||||
lChar: Char;
|
||||
begin
|
||||
lFieldValue := '';
|
||||
lChar := C(0).ToLower;
|
||||
|
||||
if (lChar = 'n') and (C(1).ToLower = 'u') and (C(2).ToLower = 'l') and (C(3).ToLower = 'l') then
|
||||
begin
|
||||
Skip(4);
|
||||
Result := True;
|
||||
lFieldValue := 'NULL';
|
||||
end
|
||||
else
|
||||
Exit(False)
|
||||
end;
|
||||
|
||||
function TRQL2SQL.MatchFieldNumericValue(out lFieldValue: string): Boolean;
|
||||
var
|
||||
lChar: Char;
|
||||
|
@ -74,6 +74,36 @@ type
|
||||
class procedure Serialize(const ADict: TMVCStringDictionary; const AJSONObject: TJsonObject); inline;
|
||||
end;
|
||||
|
||||
TMVCGUIDSerializer = class(TInterfacedObject, IMVCTypeSerializer)
|
||||
public
|
||||
procedure SerializeAttribute(
|
||||
const AElementValue: TValue;
|
||||
const APropertyName: string;
|
||||
const ASerializerObject: TObject;
|
||||
const AAttributes: TArray<TCustomAttribute>
|
||||
);
|
||||
|
||||
procedure SerializeRoot(
|
||||
const AObject: TObject;
|
||||
out ASerializerObject: TObject;
|
||||
const AAttributes: TArray<TCustomAttribute>;
|
||||
const ASerializationAction: TMVCSerializationAction = nil
|
||||
);
|
||||
|
||||
procedure DeserializeAttribute(
|
||||
var AElementValue: TValue;
|
||||
const APropertyName: string;
|
||||
const ASerializerObject: TObject;
|
||||
const AAttributes: TArray<TCustomAttribute>
|
||||
);
|
||||
|
||||
procedure DeserializeRoot(
|
||||
const ASerializerObject: TObject;
|
||||
const AObject: TObject;
|
||||
const AAttributes: TArray<TCustomAttribute>
|
||||
);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@ -249,4 +279,59 @@ begin
|
||||
ASerializerObject := lOutObject;
|
||||
end;
|
||||
|
||||
{ TMVCGUIDSerializer }
|
||||
|
||||
procedure TMVCGUIDSerializer.DeserializeAttribute(var AElementValue: TValue; const APropertyName: string;
|
||||
const ASerializerObject: TObject; const AAttributes: TArray<TCustomAttribute>);
|
||||
|
||||
function GUIDFromString(const AString: string): TGUID;
|
||||
var
|
||||
LGuidStr: string;
|
||||
begin
|
||||
// delphi uuid format: {ae502abe-430b-b23a-2878-2d18d6a6e465}
|
||||
|
||||
// string uuid without braces and dashes: ae502abe430bb23a28782d18d6a6e465
|
||||
if AString.Length = 32 then
|
||||
LGuidStr := Format('{%s-%s-%s-%s-%s}', [AString.Substring(0, 8), AString.Substring(8, 4),
|
||||
AString.Substring(12, 4), AString.Substring(16, 4),AString.Substring(20, 12)])
|
||||
|
||||
// string uuid without braces: ae502abe-430b-b23a-2878-2d18d6a6e465
|
||||
else if AString.Length = 36 then
|
||||
LGuidStr := Format('{%s}', [AString])
|
||||
else
|
||||
LGuidStr := AString;
|
||||
Result := StringToGUID(LGuidStr);
|
||||
end;
|
||||
|
||||
var
|
||||
LJson: TJDOJsonObject;
|
||||
LGuid: TGUID;
|
||||
begin
|
||||
LJson := ASerializerObject as TJDOJsonObject;
|
||||
if LJSON.Values[APropertyName].Typ in [jdtNone, jdtObject] then { json nulls are recognized as jdtObject }
|
||||
LGuid := TGUID.Empty
|
||||
else
|
||||
LGuid := GUIDFromString(LJSON.S[APropertyName]);
|
||||
AElementValue := TValue.From<TGUID>(LGuid);
|
||||
end;
|
||||
|
||||
procedure TMVCGUIDSerializer.DeserializeRoot(const ASerializerObject, AObject: TObject;
|
||||
const AAttributes: TArray<TCustomAttribute>);
|
||||
begin
|
||||
// not implemented
|
||||
end;
|
||||
|
||||
procedure TMVCGUIDSerializer.SerializeAttribute(const AElementValue: TValue; const APropertyName: string;
|
||||
const ASerializerObject: TObject; const AAttributes: TArray<TCustomAttribute>);
|
||||
begin
|
||||
(ASerializerObject as TJDOJsonObject).S[APropertyName] := AElementValue.AsType<TGUID>.ToString;
|
||||
end;
|
||||
|
||||
procedure TMVCGUIDSerializer.SerializeRoot(const AObject: TObject; out ASerializerObject: TObject;
|
||||
const AAttributes: TArray<TCustomAttribute>; const ASerializationAction: TMVCSerializationAction);
|
||||
begin
|
||||
// not implemented
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
@ -176,6 +176,8 @@ begin
|
||||
GetTypeSerializers.Add(TypeInfo(TMemoryStream), lStreamSerializer);
|
||||
fStringDictionarySerializer := TMVCStringDictionarySerializer.Create;
|
||||
GetTypeSerializers.Add(TypeInfo(TMVCStringDictionary), TMVCStringDictionarySerializer.Create);
|
||||
GetTypeSerializers.Add(TypeInfo(TGUID), TMVCGUIDSerializer.Create);
|
||||
|
||||
end;
|
||||
|
||||
procedure TMVCJsonDataObjectsSerializer.AttributeToJsonDataValue(const AJsonObject: TJDOJsonObject;
|
||||
|
@ -1,3 +1,5 @@
|
||||
ne(value,null)
|
||||
eq(value,null)
|
||||
eq(value,false)
|
||||
eq(value,true)
|
||||
in ( value , [ 1 , 2 , 3 ] )
|
||||
|
@ -216,6 +216,13 @@ type
|
||||
property NullableString: TMVCNullable<string> read FNullableString write FNullableString;
|
||||
end;
|
||||
|
||||
TEntityCustomWithGuid = class(TEntityCustom)
|
||||
private
|
||||
FGuidValue: TGUID;
|
||||
public
|
||||
property GuidValue: TGUID read FGuidValue write FGuidValue;
|
||||
end;
|
||||
|
||||
TColorEnum = (RED, GREEN, BLUE);
|
||||
|
||||
TEntityWithEnums = class
|
||||
|
@ -103,6 +103,8 @@ type
|
||||
procedure TestSerializeDeSerializeEntityWithEnums;
|
||||
[Test]
|
||||
procedure TestStringDictionary;
|
||||
[Test]
|
||||
procedure TestSerializeDeserializeGuid;
|
||||
|
||||
end;
|
||||
|
||||
@ -1273,6 +1275,44 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMVCTestSerializerJsonDataObjects.TestSerializeDeserializeGuid;
|
||||
const
|
||||
JSON =
|
||||
'{' +
|
||||
'"GuidValue":"{AEED1A0F-9061-40F0-9FDA-D69AE7F20222}",' +
|
||||
'"Id":1,' +
|
||||
'"Code":2,' +
|
||||
'"Name":"João Antônio"' +
|
||||
'}';
|
||||
var
|
||||
LEntity: TEntityCustomWithGuid;
|
||||
LJson: string;
|
||||
begin
|
||||
LEntity := TEntityCustomWithGuid.Create;
|
||||
try
|
||||
LEntity.Id := 1;
|
||||
LEntity.Code := 2;
|
||||
LEntity.name := 'João Antônio';
|
||||
LEntity.GuidValue := StringToGuid('{AEED1A0F-9061-40F0-9FDA-D69AE7F20222}');
|
||||
|
||||
LJson := FSerializer.SerializeObject(LEntity);
|
||||
Assert.AreEqual(JSON, LJson);
|
||||
finally
|
||||
LEntity.Free;
|
||||
end;
|
||||
|
||||
LEntity := TEntityCustomWithGuid.Create;
|
||||
try
|
||||
FSerializer.DeserializeObject(LJson, LEntity);
|
||||
Assert.AreEqual(Int64(1), LEntity.Id);
|
||||
Assert.AreEqual(Integer(2), LEntity.Code);
|
||||
Assert.AreEqual('João Antônio', LEntity.name);
|
||||
Assert.AreEqual(StringToGuid('{AEED1A0F-9061-40F0-9FDA-D69AE7F20222}'), LEntity.GuidValue);
|
||||
finally
|
||||
LEntity.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMVCTestSerializerJsonDataObjects.TestSerializeNil;
|
||||
begin
|
||||
Assert.areEqual('null', FSerializer.SerializeObject(nil));
|
||||
|
Loading…
Reference in New Issue
Block a user