27 |
|
{ IBX For Lazarus (Firebird Express) } |
28 |
|
{ Contributor: Tony Whyman, MWA Software http://www.mwasoftware.co.uk } |
29 |
|
{ Portions created by MWA Software are copyright McCallum Whyman } |
30 |
< |
{ Associates Ltd 2011 - 2015 } |
30 |
> |
{ Associates Ltd 2011 - 2015 } |
31 |
|
{ } |
32 |
|
{************************************************************************} |
33 |
|
|
441 |
|
FInTransactionEnd: boolean; |
442 |
|
FIBLinks: TList; |
443 |
|
FFieldColumns: PFieldColumns; |
444 |
+ |
FBufferUpdatedOnQryReturn: boolean; |
445 |
|
procedure ColumnDataToBuffer(QryResults: IResults; ColumnIndex, |
446 |
|
FieldIndex: integer; Buffer: PChar); |
447 |
|
procedure InitModelBuffer(Qry: TIBSQL; Buffer: PChar); |
686 |
|
procedure Post; override; |
687 |
|
function ParamByName(ParamName: String): ISQLParam; |
688 |
|
property ArrayFieldCount: integer read FArrayFieldCount; |
689 |
+ |
property DatabaseInfo: TIBDatabaseInfo read FDatabaseInfo; |
690 |
|
property UpdateObject: TIBDataSetUpdateObject read FUpdateObject write SetUpdateObject; |
691 |
|
property UpdatesPending: Boolean read FUpdatesPending; |
692 |
|
property UpdateRecordTypes: TIBUpdateRecordTypes read FUpdateRecordTypes |
2065 |
|
begin |
2066 |
|
j := GetFieldPosition(QryResults[i].GetAliasName); |
2067 |
|
if j > 0 then |
2068 |
+ |
begin |
2069 |
|
ColumnDataToBuffer(QryResults,i,j,Buffer); |
2070 |
+ |
FBufferUpdatedOnQryReturn := true; |
2071 |
+ |
end; |
2072 |
|
end; |
2073 |
|
end; |
2074 |
|
|
2079 |
|
ColumnIndex, FieldIndex: integer; Buffer: PChar); |
2080 |
|
var |
2081 |
|
LocalData: PByte; |
2082 |
< |
LocalDate, LocalDouble: Double; |
2082 |
> |
LocalDate: TDateTime; |
2083 |
> |
LocalDouble: Double; |
2084 |
|
LocalInt: Integer; |
2085 |
|
LocalBool: wordBool; |
2086 |
|
LocalInt64: Int64; |
2087 |
|
LocalCurrency: Currency; |
2082 |
– |
p: PRecordData; |
2088 |
|
ColData: ISQLData; |
2089 |
|
begin |
2085 |
– |
p := PRecordData(Buffer); |
2090 |
|
LocalData := nil; |
2091 |
< |
with p^.rdFields[FieldIndex], FFieldColumns^[FieldIndex] do |
2091 |
> |
with PRecordData(Buffer)^.rdFields[FieldIndex], FFieldColumns^[FieldIndex] do |
2092 |
|
begin |
2093 |
|
QryResults.GetData(ColumnIndex,fdIsNull,fdDataLength,LocalData); |
2094 |
|
if not fdIsNull then |
2095 |
|
begin |
2096 |
|
ColData := QryResults[ColumnIndex]; |
2097 |
|
case fdDataType of {Get Formatted data for column types that need formatting} |
2098 |
+ |
SQL_TYPE_DATE, |
2099 |
+ |
SQL_TYPE_TIME, |
2100 |
|
SQL_TIMESTAMP: |
2101 |
|
begin |
2102 |
< |
LocalDate := TimeStampToMSecs(DateTimeToTimeStamp(ColData.AsDateTime)); |
2102 |
> |
{This is an IBX native format and not the TDataset approach. See also GetFieldData} |
2103 |
> |
LocalDate := ColData.AsDateTime; |
2104 |
|
LocalData := PByte(@LocalDate); |
2105 |
|
end; |
2099 |
– |
SQL_TYPE_DATE: |
2100 |
– |
begin |
2101 |
– |
LocalInt := DateTimeToTimeStamp(ColData.AsDateTime).Date; |
2102 |
– |
LocalData := PByte(@LocalInt); |
2103 |
– |
end; |
2104 |
– |
SQL_TYPE_TIME: |
2105 |
– |
begin |
2106 |
– |
LocalInt := DateTimeToTimeStamp(ColData.AsDateTime).Time; |
2107 |
– |
LocalData := PByte(@LocalInt); |
2108 |
– |
end; |
2106 |
|
SQL_SHORT, SQL_LONG: |
2107 |
|
begin |
2108 |
|
if (fdDataScale = 0) then |
2458 |
|
end; |
2459 |
|
Inc(arr); |
2460 |
|
end; |
2461 |
+ |
FBufferUpdatedOnQryReturn := false; |
2462 |
|
if Assigned(FUpdateObject) then |
2463 |
|
begin |
2464 |
|
if (Qry = FQDelete) then |
2471 |
|
else begin |
2472 |
|
SetInternalSQLParams(Qry.Params, Buff); |
2473 |
|
Qry.ExecQuery; |
2474 |
+ |
if Qry.FieldCount > 0 then {Has RETURNING Clause} |
2475 |
+ |
UpdateRecordFromQuery(Qry.Current,Buff); |
2476 |
|
end; |
2477 |
– |
if Qry.FieldCount > 0 then {Has RETURNING Clause} |
2478 |
– |
UpdateRecordFromQuery(Qry.Current,Buff); |
2477 |
|
PRecordData(Buff)^.rdUpdateStatus := usUnmodified; |
2478 |
|
PRecordData(Buff)^.rdCachedUpdateStatus := cusUnmodified; |
2479 |
|
SetModified(False); |
2480 |
|
WriteRecordCache(PRecordData(Buff)^.rdRecordNumber, Buff); |
2481 |
< |
if (FForcedRefresh or FNeedsRefresh) and CanRefresh then |
2481 |
> |
if (FForcedRefresh or (FNeedsRefresh and not FBufferUpdatedOnQryReturn)) and CanRefresh then |
2482 |
|
InternalRefreshRow; |
2483 |
|
end; |
2484 |
|
|
2714 |
|
|
2715 |
|
procedure TIBCustomDataSet.SetDatabase(Value: TIBDatabase); |
2716 |
|
begin |
2717 |
< |
if (FBase.Database <> Value) then |
2717 |
> |
if (csLoading in ComponentState) or (FBase.Database <> Value) then |
2718 |
|
begin |
2719 |
|
CheckDatasetClosed; |
2720 |
|
InternalUnPrepare; |
2829 |
|
end; |
2830 |
|
SQL_BLOB, SQL_ARRAY, SQL_QUAD: |
2831 |
|
Param.AsQuad := PISC_QUAD(data)^; |
2832 |
< |
SQL_TYPE_DATE: |
2833 |
< |
begin |
2836 |
< |
ts.Date := PInt(data)^; |
2837 |
< |
ts.Time := 0; |
2838 |
< |
Param.AsDate := TimeStampToDateTime(ts); |
2839 |
< |
end; |
2840 |
< |
SQL_TYPE_TIME: |
2841 |
< |
begin |
2842 |
< |
ts.Date := 0; |
2843 |
< |
ts.Time := PInt(data)^; |
2844 |
< |
Param.AsTime := TimeStampToDateTime(ts); |
2845 |
< |
end; |
2832 |
> |
SQL_TYPE_DATE, |
2833 |
> |
SQL_TYPE_TIME, |
2834 |
|
SQL_TIMESTAMP: |
2835 |
< |
Param.AsDateTime := |
2836 |
< |
TimeStampToDateTime(MSecsToTimeStamp(trunc(PDouble(data)^))); |
2835 |
> |
{This is an IBX native format and not the TDataset approach. See also SetFieldData} |
2836 |
> |
Param.AsDateTime := PDateTime(data)^; |
2837 |
|
SQL_BOOLEAN: |
2838 |
|
Param.AsBoolean := PWordBool(data)^; |
2839 |
|
end; |
4160 |
|
for i := 0 to SQLParams.GetCount - 1 do |
4161 |
|
begin |
4162 |
|
cur_field := DataSource.DataSet.FindField(SQLParams[i].Name); |
4163 |
< |
cur_param := SQLParams[i]; |
4164 |
< |
if (cur_field <> nil) then begin |
4163 |
> |
if (cur_field <> nil) then |
4164 |
> |
begin |
4165 |
> |
cur_param := SQLParams[i]; |
4166 |
|
if (cur_field.IsNull) then |
4167 |
|
cur_param.IsNull := True |
4168 |
< |
else case cur_field.DataType of |
4168 |
> |
else |
4169 |
> |
case cur_field.DataType of |
4170 |
|
ftString: |
4171 |
|
cur_param.AsString := cur_field.AsString; |
4172 |
|
ftBoolean: |
4176 |
|
ftInteger: |
4177 |
|
cur_param.AsLong := cur_field.AsInteger; |
4178 |
|
ftLargeInt: |
4179 |
< |
cur_param.AsInt64 := TLargeIntField(cur_field).AsLargeInt; |
4179 |
> |
cur_param.AsInt64 := cur_field.AsLargeInt; |
4180 |
|
ftFloat, ftCurrency: |
4181 |
|
cur_param.AsDouble := cur_field.AsFloat; |
4182 |
|
ftBCD: |
4930 |
|
function TIBCustomDataSet.GetFieldData(Field: TField; Buffer: Pointer; |
4931 |
|
NativeFormat: Boolean): Boolean; |
4932 |
|
begin |
4933 |
< |
if (Field.DataType = ftBCD) and not NativeFormat then |
4933 |
> |
{These datatypes use IBX conventions and not TDataset conventions} |
4934 |
> |
if (Field.DataType in [ftBCD,ftDateTime,ftDate,ftTime]) and not NativeFormat then |
4935 |
|
Result := InternalGetFieldData(Field, Buffer) |
4936 |
|
else |
4937 |
|
Result := inherited GetFieldData(Field, Buffer, NativeFormat); |
4957 |
|
procedure TIBCustomDataSet.SetFieldData(Field: TField; Buffer: Pointer; |
4958 |
|
NativeFormat: Boolean); |
4959 |
|
begin |
4960 |
< |
if (not NativeFormat) and (Field.DataType = ftBCD) then |
4960 |
> |
{These datatypes use IBX conventions and not TDataset conventions} |
4961 |
> |
if (not NativeFormat) and (Field.DataType in [ftBCD,ftDateTime,ftDate,ftTime]) then |
4962 |
|
InternalSetfieldData(Field, Buffer) |
4963 |
|
else |
4964 |
|
inherited SetFieldData(Field, buffer, NativeFormat); |