diff options
| author | michael <michael@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2010-05-27 15:22:02 +0000 |
|---|---|---|
| committer | michael <michael@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2010-05-27 15:22:02 +0000 |
| commit | 61eb0a772624e0afa632cd40bd03392c2a04d584 (patch) | |
| tree | e8199d2c0fd175e5b3c3204243a552cefd338a56 /packages/fcl-web/src/webdata/extjsjson.pp | |
| parent | 7dd6357f616913a5bce8886fee5f4dea165b033f (diff) | |
| download | fpc-61eb0a772624e0afa632cd40bd03392c2a04d584.tar.gz | |
* Added webdata
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@15334 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages/fcl-web/src/webdata/extjsjson.pp')
| -rw-r--r-- | packages/fcl-web/src/webdata/extjsjson.pp | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/packages/fcl-web/src/webdata/extjsjson.pp b/packages/fcl-web/src/webdata/extjsjson.pp new file mode 100644 index 0000000000..62ff604358 --- /dev/null +++ b/packages/fcl-web/src/webdata/extjsjson.pp @@ -0,0 +1,362 @@ +unit extjsjson; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, httpdefs, fphttp,fpwebdata, fpextjs, fpjson, db, jsonparser; + +type + + { TExtJSJSonWebdataInputAdaptor } + + TExtJSJSonWebdataInputAdaptor = CLass(TCustomWebdataInputAdaptor) + private + FRows : TJSONArray; + FCurrentRow : TJSONObject; + FIDValue : TJSONData; + FRowIndex : integer; + function CheckData: Boolean; + Public + Function GetNextBatch : Boolean; override; + Function TryFieldValue(Const AFieldName : String; out AValue : String) : Boolean; override; + Destructor destroy; override; + end; + { TExtJSJSONDataFormatter } + + TExtJSJSONDataFormatter = Class(TExtJSDataFormatter) + private + procedure SendSuccess(ResponseContent: TStream; AddIDValue : Boolean = False); + protected + Function CreateAdaptor(ARequest : TRequest) : TCustomWebdataInputAdaptor; override; + Function AddFieldToJSON(O: TJSONObject; AFieldName: String; F: TField): TJSONData; + function GetDataContentType: String; override; + Function GetJSONMetaData: TJSONObject; + function RowToJSON: TJSONObject; + procedure DatasetToStream(Stream: TStream); override; + Procedure DoExceptionToStream(E : Exception; ResponseContent : TStream); override; + Procedure DoInsertRecord(ResponseContent : TStream); override; + Procedure DoUpdateRecord(ResponseContent : TStream); override; + Procedure DoDeleteRecord(ResponseContent : TStream); override; + end; + +implementation +{ $define wmdebug} +{$ifdef wmdebug} +uses dbugintf; +{$endif wmdebug} + +Resourcestring + SErrWrongDataFormat = 'Post ROWS data has wrong value type. Expected array or object, got : %s.'; + SerrNoExceptionMessage = 'No exception to take error message from.'; + +Const + // Do not localize these strings + SDefMetaDataProperty = 'metaData'; + SDefFieldsProperty = 'fields'; + SDefFieldProperty = 'field'; + SDefFieldNameProperty = 'name'; + SDefDirectionProperty = 'direction'; + SDefSortInfoProperty = 'sortInfo'; + SDefAscDesc : Array[Boolean] of string = ('ASC','DESC'); + +function TExtJSJSONDataFormatter.GetDataContentType: String; +begin + Result:='text/html'; +end; + +function TExtJSJSONDataFormatter.CreateAdaptor(ARequest: TRequest + ): TCustomWebdataInputAdaptor; +begin + Result:=TExtJSJSonWebdataInputAdaptor.Create(Self); + Result.Request:=ARequest; +end; + +function TExtJSJSONDataFormatter.AddFieldToJSON(O : TJSONObject; AFieldName : String; F : TField): TJSONData; + +begin + Case F.DataType of + ftSmallint, + ftInteger, + ftAutoInc, + ftWord: + Result:=O.Items[O.Add(AFieldName,F.AsInteger)]; + ftBoolean: + Result:=O.Items[O.Add(AFieldName,F.AsBoolean)]; + ftLargeint: + Result:=O.Items[O.Add(AFieldName,F.AsLargeInt)]; + else + Result:=O.Items[O.Add(AFieldName,F.DisplayText)]; + end; +end; + +function TExtJSJSONDataFormatter.RowToJSON: TJSONObject; + +Var + F : TField; + I : Integer; + + +begin + Result:=TJSONObject.Create(); + For I:=0 to Dataset.Fields.Count-1 do + begin + F:=Dataset.Fields[I]; + AddFieldToJSON(Result,F.FieldName,F); + end; +end; + +Function TExtJSJSONDataFormatter.GetJSONMetaData: TJSONObject; + +Var + F : TJSONArray; + Fi : TField; + I : Integer; + O : TJSONObject; + SF : String; + +begin + If (SortField='') then + SF:=Dataset.Fields[0].FieldName + else + SF:=SortField; + Result:=TJSonObject.Create; + try + F:=TJSONArray.Create; + Result.add(SDefFieldsProperty,F); + For I:=0 to Dataset.Fields.Count-1 do + begin + Fi:=Dataset.Fields[i]; + O:=TJSONObject.Create(); + O.Add(SDefFieldNameProperty,Fi.FieldName); + F.Add(O); + end; + O:=TJSONObject.Create(); + O.Add(SDefFieldProperty,SF); + O.Add(SDefDirectionProperty,SDefAscDesc[SortDescending]); + Result.Add(SDefSortInfoProperty,O); + except + Result.free; + Raise; + end; +end; + +procedure TExtJSJSONDataFormatter.DatasetToStream(Stream: TStream); + +Var + Rows : TJSONArray; + Meta,Resp : TJSONObject; + L : String; + DS : TDataset; + i,RCount,ACount : Integer; + +begin + Rows:=Nil; + Resp:=TJSONObject.Create; + try + Rows:=TJSONArray.Create(); + DS:=Dataset; + DS.First; + RCount:=0; + If MetaData then + begin + Meta:=GetJSONMetaData; + Resp.Add(SDefMetaDataProperty,Meta); + end; + // Go to start + ACount:=PageStart; + While (Not DS.EOF) and (ACount>0) do + begin + DS.Next; + Dec(ACount); + Inc(RCount); + end; + ACount:=PageSize; + While (not DS.EOF) and ((PageSize=0) or (ACount>0)) do + begin + Inc(RCount); + Dec(ACount); + Rows.Add(RowToJSON); + DS.Next; + end; + If (PageSize>0) then + While (not DS.EOF) do + begin + Inc(RCount); + DS.Next; + end; + Resp.Add(RowsProperty,Rows); + Resp.Add(SuccessProperty,True); + If (PageSize>0) then + Resp.Add(TotalProperty,RCount); + L:=Resp.AsJSON; + Stream.WriteBuffer(L[1],Length(L)); + finally + Resp.Free; + end; +end; + +procedure TExtJSJSONDataFormatter.DoExceptionToStream(E: Exception; + ResponseContent: TStream); + +Var + Resp : TJSonObject; + L : String; + +begin + Resp:=tjsonObject.Create(); + try + Resp.Add(SuccessProperty,False); + If Assigned(E) then + Resp.Add(MessageProperty,E.Message) + else + Resp.Add(MessageProperty,SerrNoExceptionMessage); + L:=Resp.AsJSON; + If Length(L)>0 then + ResponseContent.WriteBuffer(L[1],Length(L)); + finally + Resp.Free; + end; +end; + +procedure TExtJSJSONDataFormatter.SendSuccess(ResponseContent: TStream; AddIDValue : Boolean = False); + +Var + Resp : TJSonObject; + L : String; + +begin + try + Resp:=TJsonObject.Create; + Resp.Add(SuccessProperty,True); + Resp.Add(Provider.IDFieldName,Provider.IDFieldValue); + L:=Resp.AsJSON; + ResponseContent.WriteBuffer(L[1],Length(L)); + finally + Resp.Free; + end; +end; + +procedure TExtJSJSONDataFormatter.DoInsertRecord(ResponseContent: TStream); + +begin + Inherited; + SendSuccess(ResponseContent,True); +end; + +procedure TExtJSJSONDataFormatter.DoUpdateRecord(ResponseContent: TStream); +begin + inherited DoUpdateRecord(ResponseContent); + SendSuccess(ResponseContent,False); +end; + +procedure TExtJSJSONDataFormatter.DoDeleteRecord(ResponseContent: TStream); +begin + inherited DoDeleteRecord(ResponseContent); + SendSuccess(ResponseContent,False); +end; + +{ TExtJSJSonWebdataInputAdaptor } + +function TExtJSJSonWebdataInputAdaptor.CheckData : Boolean; + +Var + D : TJSONData; + P : TJSONParser; + S : String; + +begin + Result:=Assigned(FCurrentRow); + If Not (Result) and TryParamValue('rows',S) then + begin + {$ifdef wmdebug}senddebug('Check data: '+GetParamValue('rows'));{$endif} + P:=TJSONParser.Create(S); + try + D:=P.Parse; + {$ifdef wmdebug}senddebug('Classname : '+D.ClassName);{$endif} + If D is TJSONArray then + begin + FRows:=TJSONArray(D); + FRowIndex:=0; + FCurrentRow:=FRows.Items[0] as TJSONObject; + end + else If D is TJSONObject then + begin + FRows:=Nil; + FCurrentRow:=TJSONObject(D); + end + else if D is TJSONInt64Number then + FIDValue:=D + else + begin + FreeAndNil(D); + Raise EFPHTTPError.CreateFmt(SErrWrongDataFormat,[D.ClassName]); + end; + Result:=True; + finally + P.Free; + end; + end; +end; + +function TExtJSJSonWebdataInputAdaptor.GetNextBatch: Boolean; +begin + If (FRows=Nil) then + Result:=inherited GetNextBatch + else + begin + Result:=FRowindex<FRows.Count-1; + Inc(FRowIndex); + If Result then + FCurrentRow:=FRows.Items[FRowIndex] as TJSONObject + else + FCurrentRow:=Nil; + end; +end; + +function TExtJSJSonWebdataInputAdaptor.TryFieldValue(const AFieldName: String; + out AValue: String): Boolean; + +Var + I : Integer; + +begin + Result:=False; + if CheckData then + begin + If Assigned(FIDValue) and (0=CompareText(AFieldName,'ID')) then + begin + AValue:=FIDValue.AsString; + Result:=True; + end + else + begin + I:=FCurrentRow.IndexOfName(AFieldName); + Result:=I<>-1; + if result then + AValue:=FCurrentRow.Items[I].AsString; + end; + end; +end; + +destructor TExtJSJSonWebdataInputAdaptor.destroy; +begin + If Assigned(FRows) then + FreeAndNil(FRows) + else if assigned(FCurrentRow) then + FreeAndNil(FCurrentRow) + else if Assigned(FIDValue) then + FreeAndNil(FIDValue); + inherited destroy; +end; + +initialization + WebDataProviderManager.RegisterInputAdaptor('ExtJS - JSON',TExtJSJSONWebdataInputAdaptor); + WebDataProviderManager.RegisterDataProducer('ExtJS - JSON',TExtJSJSONDataFormatter); + +finalization + WebDataProviderManager.UnRegisterInputAdaptor('ExtJS - JSON'); + WebDataProviderManager.UnRegisterDataProducer('ExtJS - JSON') +end. + |
