{ This file is part of the Free Pascal run time library. Copyright (c) 2018 by Michael Van Canneyt, member of the Free Pascal development team Remobjects Data Abstract external classes. 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 DA; {$mode objfpc} {$modeswitch externalclass} interface uses Sysutils, Types, JS, DASDK; Type TDADataType = ( datUnknown, datString, datDateTime, datFloat, datCurrency, datAutoInc, datInteger, datLargeInt, datBoolean, datMemo, datBlob, datWideString, datWideMemo, datLargeAutoInc, datByte, datShortInt, datWord, datSmallInt, datCardinal, datLargeUInt, datGuid, datXml, datDecimal, datSingleFloat, datFixedChar, datFixedWideChar, datCursor); // Forward classes TDADataTable = class; TDABIN2DataStreamer = class; TDAJSONDataStreamer = class; TDARemoteDataAdapter = Class; TDAChange = class; TDADelta = class; TDADeltas = class; TDAField = class; TDALookupField = class; TDADataTableRow = class; TDAExpression = class; TDADynamicWhere = class; TDAConstantExpression = class; TDAParameterExpression = class; TDANullExpression = class; TDAFieldExpression = class; TDAMacroExpression = class; TDAUnaryExpression = class; TDABinaryExpression = class; TDABetweenExpression = class; TDAListExpression = class; TDAUtil = Class; TDARemoteDataAdaptor = Class; TDAStream = String; TDADataStreamer = class external name 'RemObjects.DataAbstract.DataStreamer' (TJSObject) Public procedure initializeRead; procedure initializeWrite; procedure finalizeWrite; function getStream : TDAStream; procedure setStream(aStream : TDAStream); procedure readDataset(aDataset : TDADataTable); function readDelta : TDADeltas; procedure writeDelta(aDelta : TDADeltas); Property Stream : TDAStream Read getStream write setStream; end; TDADataStreamerClass = Class of TDADataStreamer; TDABIN2DataStreamer = class external name 'RemObjects.DataAbstract.Bin2DataStreamer' (TDADataStreamer) function readByte : Byte; function readInteger : NativeInt; function readAnsiStringWithLength : String; function readUtf8StringWithLength : string; function read (aType : string) : TJSObject; function readParam (acount : Integer) : TDADataParameter; function readField(acount : Integer) : TDAField; Procedure writeByte(aValue : Byte); Procedure writeInteger(aValue : NativeInt); Procedure writeAnsiStringWithLength(aValue : String); Procedure write(aType : string; aValue : TJSObject); end; TDAJSONDataStreamer = class external name 'RemObjects.DataAbstract.JSONDataStreamer' (TDADataStreamer) end; TDARemoteDataAdapter = Class external name 'RemObjects.DataAbstract.RemoteDataAdapter' (TJSObject) Public Constructor New(Const aURL, aDataServiceName, aLoginServiceName : String; aStreamerClass : TDADataStreamerClass); end; TDAChange = class external name 'RemObjects.DataAbstract.Change' (TJSObject) recid : Nativeint; changetype : string; status : string; message : string; old : TJSValueDynArray; new_ : TJSValueDynArray; external name 'new'; end; TDAChangeArray = array of TDAChange; TLogField = record name : string; datatype : string; external name 'type'; end; TLogFieldArray = array of TLogfield; TDADelta = class external name 'RemObjects.DataAbstract.Delta' (TJSObject) Private FData : TDAChangeArray; external name 'data'; FKeyFields : TStringDynArray; external name 'keyfields'; FLoggedFields : TLogFieldArray; external name 'loggedfields'; FName : string; external name 'name'; Public Function intFindId(anId : Integer) : TDAChange; Property data : TDAChangeArray Read FData; Property keyFields : TStringDynArray Read FKeyFields Write FKeyFields; Property LoggedFields : TLogFieldArray Read FLoggedFields Write FLoggedFields; Property Name : String Read FName Write FName; end; TDADeltaArray = Array of TDADelta; TDADeltas = class external name 'RemObjects.DataAbstract.Deltas' (TJSObject) Public deltas : TDADeltaArray; Function FindByName (Const aName : String) : TDADelta; end; TDATableRowNotifyEvent = reference to procedure(row : TDADataTableRow); TDADataTableRowArray = array of TDADataTableRow; TDAFieldArray = Array of TDAField; TDADataTable = class external name 'RemObjects.DataAbstract.DataTable' (TJSObject) Public name : string; rows : TDADataTableRowArray; fields : TDAFieldArray; deletedrows : TDADataTableRowArray; frecordbuffer : TJSArray; fNextRecID : Integer; fIndex : Integer; bofFlag : Boolean; eofFlag : Boolean; dynamicWhere : TJSObject; onNewRecord : TDATableRowNotifyEvent; onBeforeDelete: TDATableRowNotifyEvent; onAfterDelete: TDATableRowNotifyEvent; onBeforeScroll: TDATableRowNotifyEvent; onAfterScroll: TDATableRowNotifyEvent; Procedure checkRequired; Procedure locate(aName : String; aValue : JSValue); procedure addLookupField(const aName,aSourceField : String; aLookupTable : TDADataTable; const aLookupKeyField, aLookupResultField : String); procedure getNextId; function appendRow : TDADataTableRow; procedure deleteRow; procedure markDeleted; function fieldNumByName(Const aName : string) : Integer; function fieldByName(Const aName : string) : TDAField; procedure setFieldValue(Const aName : string; aValue : JSValue); function getFieldValue(Const aName : string) : JSValue; procedure setFieldAsString(Const aName, aValue : String); function getFieldAsString(Const aName : string) : String; function currentRow : TDADataTableRow; procedure first; procedure last; procedure next; procedure prev; Function findId(anID: Integer) : TDADataTableRow; function eof : boolean; function bof : boolean; procedure post; procedure cancel; end; TDAField = class external name 'RemObjects.DataAbstract.Field' (TJSObject) Public alignment : string; blobtype: string; businessClassID : String; calculated : string; customAttributes : string; dataType : string; name: string; type_ : string external name 'type'; logChanges : boolean; readOnly : boolean; serverAutoRefresh : Boolean; serverCalculated : Boolean; description : string; decimalPrecision : Integer; decimalScale : integer; defaultValue : string; dictionaryEntry : String; displayLabel : String; displayWidth : integer; inPrimaryKey : string; visible : boolean; required : boolean; size : integer; Procedure checkReadOnly; end; TDALookupField = class external name 'RemObjects.DataAbstract.LookupField' (TJSObject) Public sourceField : string; lookupTable : TDADataTable; lookupKeyField: String; lookupResultField : string; end; TDADataTableRow = class external name 'RemObjects.DataAbstract.DataTableRow' (TJSObject) Public recID : Integer; state : string; __oldValues : array of JSValue; __newValues : array of JSValue; end; TDAExpression = class external name 'RemObjects.DataAbstract.Expression' (TJSObject) function toXML : String; end; TDADynamicWhere = class external name 'RemObjects.DataAbstract.DynamicWhere' (TJSObject) Public constructor New(anExpression : TDAExpression); function toXML : String; end; TDAConstantExpression = class external name 'RemObjects.DataAbstract.ConstantExpression' (TDAExpression) Public constructor new (aType : String; aValue : JSValue; ANull : Byte); end; TDAParameterExpression = class external name 'RemObjects.DataAbstract.ParameterExpression' (TDAExpression) Public constructor new (const aName, aType : String; aSize : Integer); end; TDANullExpression = class external name 'RemObjects.DataAbstract.NullExpression' (TDAExpression) public constructor new; end; TDAFieldExpression = class external name 'RemObjects.DataAbstract.FieldExpression' (TDAExpression) public constructor new(aName : string); end; TDAMacroExpression = class external name 'RemObjects.DataAbstract.MacroExpression' (TDAExpression) public constructor new(aName : string); end; TDAUnaryExpression = class external name 'RemObjects.DataAbstract.UnaryExpression' (TDAExpression) public constructor new(aNode : TDAExpression; aOperator : string); end; TDABinaryExpression = class external name 'RemObjects.DataAbstract.BinaryExpression' (TDAExpression) public constructor new(aNode1,aNode2 : TDAExpression; aOperator : string); end; TDABetweenExpression = class external name 'RemObjects.DataAbstract.BetweenExpression' (TDAExpression) public constructor new(aNode1,aNode2,aNode3 : TDAExpression); end; TDAListExpression = class external name 'RemObjects.DataAbstract.ListExpression' (TDAExpression) public constructor new(aList : array of TDAExpression); end; TDABinaryOperator = (dboAnd, dboOr, dboXor, dboLess, dboLessOrEqual, dboGreater, dboGreaterOrEqual, dboNotEqual, dboEqual, dboLike, dboIn, dboAddition, dboSubtraction, dboMultiply, dboDivide, dboNotIn); TDAUnaryOperator = (duoNot, duoMinus); TDAUtil = Class external name 'RemObjects.DataAbstract.Util' (TJSObject) Public function createDataParameter(aName : String;aValue : JSValue) : TJSObject; function createRequestInfo(IncludeSchema : Boolean; MaxRecords : Integer; UserFilter : String; Parameters : Array of JSValue) : TJSObject; function createRequestInfoV5(IncludeSchema : Boolean; MaxRecords : Integer; UserFilter : String; Parameters : Array of JSValue) : TJSOBject; function createRequestInfoV6(SQL : String; MaxRecords : Integer; UserFilter : String; Parameters : Array of JSValue) : TJSObject; procedure setupScriptingCallBacks; end; TDACallBack = procedure; TDALoginNeededCallBack = reference to procedure(aCallBack : TDACallBack); TDAChangeFailHandler = reference to procedure (aData : TDAChange); TDARemoteDataAdaptor = Class external name 'RemObjects.DataAbstract.RemoteDataAdapter' (TJSObject) Private FSendReducedDelta : boolean; external name 'sendReducedDelta'; Public onLoginNeeded : TDALoginNeededCallBack; onChangeFail : TDAChangeFailHandler; function getDataService() : TDADataAbstractService; function getLoginService() : TDASimpleLoginService; procedure login(aUserID,aPassword,aConnectionName : String; OnSuccess : TDASuccessEvent; OnFailed : TDAFailedEvent); procedure logout(OnSuccess : TDASuccessEvent; OnFailed : TDAFailedEvent); function createStreaer: TDAJSONDatastreamer; procedure setSendReducedDelta (aValue : Boolean); procedure getSchema(aFilter : String;OnSuccess : TDASuccessEvent; OnFailed : TDAFailedEvent); function buildDelta(aTable : TDADataTable) : TDADelta; procedure createTableFromSchema(const aTableName : String; aTable : TDADataTable; CallBack: TDACallBack); procedure executeCommand(const aName : String; Parameters: TDADataParameterArray; OnSuccess : TDASuccessEvent; OnFailed : TDAFailedEvent); function getAutoGetScripts : Boolean; procedure setAutoGetScripts(aValue : boolean); Procedure getSQLData(aTable : TDADataTable; const SQL : String;OnSuccess : TDASuccessEvent; OnFailed : TDAFailedEvent); Procedure getData(aTable : TDADataTable; aRequest : TDATableRequestInfo;OnSuccess : TDASuccessEvent; OnFailed : TDAFailedEvent); procedure applyUpdates(aTable : TDADataTable; OnSuccess : TDASuccessEvent; OnFailed : TDAFailedEvent); property sendReducedDelta : Boolean Read FSendReducedDelta Write setSendReducedDelta; property AutoGetScripts : boolean Read getAutoGetScripts write setAutoGetScripts; end; TDAHTMLTableView = class external name 'RemObjects.DataAbstract.Views.HtmlTableView' Public constructor new(aTable : TDADataTable; aHTMLTableID : String); end; TDAVerticalHTMLTableView = class external name 'RemObjects.DataAbstract.Views.VerticalHtmlTableView' Public constructor new(aTable : TDADataTable; aHTMLTableID : String); end; Const BinaryOperatorNames : Array[TDABinaryOperator] of string = ('And', 'Or', 'Xor', 'Less', 'LessOrEqual', 'Greater', 'GreaterOrEqual', 'NotEqual', 'Equal', 'Like', 'In', 'Addition', 'Subtraction', 'Multiply', 'Divide', 'NotIn'); UnaryOperatorNames: Array[TDAUnaryOperator] of string = ('Not', 'Minus'); DataTypeNames : Array[TDADataType] of string = ('Unknown', 'String', 'DateTime', 'Float', 'Currency', 'AutoInc', 'Integer', 'LargeInt', 'Boolean', 'Memo', 'Blob', 'WideString', 'WideMemo', 'LargeAutoInc', 'Byte', 'ShortInt', 'Word', 'SmallInt', 'Cardinal', 'LargeUInt', 'Guid', 'Xml', 'Decimal', 'SingleFloat', 'FixedChar', 'FixedWideChar', 'Cursor'); Function JSValueToDataType(aValue : JSValue) : TDADataType; Function JSValueToDataTypeName(aValue : JSValue) : String; Implementation Function JSValueToDataType(aValue : JSValue) : TDADataType; begin if isNull(aValue) then Result:=datUnknown else if isString(aValue) then Result:=datWideString else if isBoolean(aValue) then Result:=datBoolean else if isNumber(aValue) then begin if isInteger(aValue) then Result:=datLargeInt else Result:=datFloat end else if isDate(aValue) then Result:=datDateTime else Raise EConvertError.Create('Cannot convert JSValue to DADataType: Unknown/Unsupported type'); end; Function JSValueToDataTypeName(aValue : JSValue) : String; begin Result:=DataTypeNames[JSValueToDataType(aValue)]; end; end.