{ This file is part of the Free Pascal run time library. Copyright (c) 2019 by the Free Pascal development team SQLDB REST CSV input/output See the file COPYING.FPC, included in this distribution, for details about the copyright. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. **********************************************************************} unit sqldbrestcsv; {$mode objfpc}{$H+} interface uses Classes, SysUtils, sqldbrestio, fpjson, sqldbrestschema, csvreadwrite; Type { TCSVInputStreamer } TCSVInputStreamer = Class(TRestInputStreamer) private FCSV: TCSVParser; FValues, FFields : TStrings; Protected Property CSV : TCSVParser Read FCSV; Public Destructor Destroy; override; Function SelectObject(aIndex : Integer) : Boolean; override; function GetContentField(aName: UTF8string): TJSONData; override; procedure InitStreaming; override; end; { TCSVOutputStreamer } TCSVOutputStreamer = Class(TRestOutputStreamer) Private FCSV : TCSVBuilder; FField : integer; FRow : Integer; Public procedure EndData; override; procedure EndRow; override; procedure FinalizeOutput; override; procedure StartData; override; procedure StartRow; override; // Return Nil for null field. procedure WriteField(aPair: TRestFieldPair); override; procedure WriteMetadata(aFieldList: TRestFieldPairArray); override; Procedure CreateErrorContent(aCode : Integer; Const aMessage: String); override; Property CSV : TCSVBuilder Read FCSV; Public Destructor Destroy; override; Class Function GetContentType: String; override; procedure InitStreaming; override; end; implementation uses DateUtils; { TCSVInputStreamer } procedure TCSVInputStreamer.InitStreaming; begin FreeAndNil(FCSV); FreeAndNil(FFields); FCSV:=TCSVParser.Create; FCSV.SetSource(Stream); FCSV.QuoteChar:='"'; FCSV.Delimiter:=','; FCSV.LineEnding:=LineEnding;// FFields:=TStringList.Create; FValues:=TStringList.Create; While FCSV.ParseNextCell and (FCSV.CurrentRow=0) do FFields.Add(FCSV.CurrentCellText); end; destructor TCSVInputStreamer.Destroy; begin FreeAndNil(FCSV); FreeAndNil(FValues); FreeAndNil(FFields); inherited Destroy; end; function TCSVInputStreamer.SelectObject(aIndex: Integer): Boolean; begin Result:=(aIndex=0) and (FCSV<>Nil) and (FCSV.CurrentRow=1); if Not Result then exit; Repeat // We are on the first cell FValues.Add(FCSV.CurrentCellText); until Not (FCSV.ParseNextCell) or (FCSV.CurrentRow=2); end; function TCSVInputStreamer.GetContentField(aName: UTF8string): TJSONData; Var Idx : Integer; begin Idx:=FFields.IndexOf(aName); if (Idx>=0) and (IdxError %d: %s',[aCode,aMessage]); S:=S+Format('

Error %d : %s

',[aCode,aMessage]); Stream.WriteBuffer(S[1],Length(S)); end; destructor TCSVOutputStreamer.Destroy; begin FreeAndNil(FCSV); inherited Destroy; end; procedure TCSVOutputStreamer.InitStreaming; begin FCSV:=TCSVBuilder.Create; FCSV.SetOutput(Stream); FCSV.QuoteChar:='"'; FCSV.Delimiter:=','; FCSV.QuoteOuterWhitespace:=True; end; initialization TCSVInputStreamer.RegisterStreamer('CSV'); TCSVOutputStreamer.RegisterStreamer('CSV'); end.