315 |
|
FFieldName: string; |
316 |
|
FGeneratorName: string; |
317 |
|
FIncrement: integer; |
318 |
+ |
FQuery: TIBSQL; |
319 |
+ |
function GetDatabase: TIBDatabase; |
320 |
+ |
function GetTransaction: TIBTransaction; |
321 |
+ |
procedure SetDatabase(AValue: TIBDatabase); |
322 |
+ |
procedure SetGeneratorName(AValue: string); |
323 |
|
procedure SetIncrement(const AValue: integer); |
324 |
+ |
procedure SetTransaction(AValue: TIBTransaction); |
325 |
+ |
procedure SetQuerySQL; |
326 |
|
protected |
327 |
< |
function GetNextValue(ADatabase: TIBDatabase; ATransaction: TIBTransaction): integer; |
327 |
> |
function GetNextValue: integer; |
328 |
|
public |
329 |
|
constructor Create(Owner: TIBCustomDataSet); |
330 |
+ |
destructor Destroy; override; |
331 |
|
procedure Apply; |
332 |
|
property Owner: TIBCustomDataSet read FOwner; |
333 |
+ |
property Database: TIBDatabase read GetDatabase write SetDatabase; |
334 |
+ |
property Transaction: TIBTransaction read GetTransaction write SetTransaction; |
335 |
|
published |
336 |
< |
property Generator: string read FGeneratorName write FGeneratorName; |
336 |
> |
property Generator: string read FGeneratorName write SetGeneratorName; |
337 |
|
property Field: string read FFieldName write FFieldName; |
338 |
|
property Increment: integer read FIncrement write SetIncrement default 1; |
339 |
|
property ApplyOnEvent: TIBGeneratorApplyOnEvent read FApplyOnEvent write FApplyOnEvent; |
2074 |
|
ColumnIndex, FieldIndex: integer; Buffer: PChar); |
2075 |
|
var |
2076 |
|
LocalData: PByte; |
2077 |
< |
LocalDate, LocalDouble: Double; |
2077 |
> |
LocalDate: TDateTime; |
2078 |
> |
LocalDouble: Double; |
2079 |
|
LocalInt: Integer; |
2080 |
|
LocalBool: wordBool; |
2081 |
|
LocalInt64: Int64; |
2082 |
|
LocalCurrency: Currency; |
2072 |
– |
p: PRecordData; |
2083 |
|
ColData: ISQLData; |
2084 |
|
begin |
2075 |
– |
p := PRecordData(Buffer); |
2085 |
|
LocalData := nil; |
2086 |
< |
with p^.rdFields[FieldIndex], FFieldColumns^[FieldIndex] do |
2086 |
> |
with PRecordData(Buffer)^.rdFields[FieldIndex], FFieldColumns^[FieldIndex] do |
2087 |
|
begin |
2088 |
|
QryResults.GetData(ColumnIndex,fdIsNull,fdDataLength,LocalData); |
2089 |
|
if not fdIsNull then |
2090 |
|
begin |
2091 |
|
ColData := QryResults[ColumnIndex]; |
2092 |
|
case fdDataType of {Get Formatted data for column types that need formatting} |
2093 |
+ |
SQL_TYPE_DATE, |
2094 |
+ |
SQL_TYPE_TIME, |
2095 |
|
SQL_TIMESTAMP: |
2096 |
|
begin |
2097 |
< |
LocalDate := TimeStampToMSecs(DateTimeToTimeStamp(ColData.AsDateTime)); |
2097 |
> |
{This is an IBX native format and not the TDataset approach. See also GetFieldData} |
2098 |
> |
LocalDate := ColData.AsDateTime; |
2099 |
|
LocalData := PByte(@LocalDate); |
2100 |
|
end; |
2089 |
– |
SQL_TYPE_DATE: |
2090 |
– |
begin |
2091 |
– |
LocalInt := DateTimeToTimeStamp(ColData.AsDateTime).Date; |
2092 |
– |
LocalData := PByte(@LocalInt); |
2093 |
– |
end; |
2094 |
– |
SQL_TYPE_TIME: |
2095 |
– |
begin |
2096 |
– |
LocalInt := DateTimeToTimeStamp(ColData.AsDateTime).Time; |
2097 |
– |
LocalData := PByte(@LocalInt); |
2098 |
– |
end; |
2101 |
|
SQL_SHORT, SQL_LONG: |
2102 |
|
begin |
2103 |
|
if (fdDataScale = 0) then |
2719 |
|
FQSelect.Database := Value; |
2720 |
|
FQModify.Database := Value; |
2721 |
|
FDatabaseInfo.Database := Value; |
2722 |
+ |
FGeneratorField.Database := Value; |
2723 |
|
end; |
2724 |
|
end; |
2725 |
|
|
2823 |
|
end; |
2824 |
|
SQL_BLOB, SQL_ARRAY, SQL_QUAD: |
2825 |
|
Param.AsQuad := PISC_QUAD(data)^; |
2826 |
< |
SQL_TYPE_DATE: |
2827 |
< |
begin |
2825 |
< |
ts.Date := PInt(data)^; |
2826 |
< |
ts.Time := 0; |
2827 |
< |
Param.AsDate := TimeStampToDateTime(ts); |
2828 |
< |
end; |
2829 |
< |
SQL_TYPE_TIME: |
2830 |
< |
begin |
2831 |
< |
ts.Date := 0; |
2832 |
< |
ts.Time := PInt(data)^; |
2833 |
< |
Param.AsTime := TimeStampToDateTime(ts); |
2834 |
< |
end; |
2826 |
> |
SQL_TYPE_DATE, |
2827 |
> |
SQL_TYPE_TIME, |
2828 |
|
SQL_TIMESTAMP: |
2829 |
< |
Param.AsDateTime := |
2830 |
< |
TimeStampToDateTime(MSecsToTimeStamp(trunc(PDouble(data)^))); |
2829 |
> |
{This is an IBX native format and not the TDataset approach. See also SetFieldData} |
2830 |
> |
Param.AsDateTime := PDateTime(data)^; |
2831 |
|
SQL_BOOLEAN: |
2832 |
|
Param.AsBoolean := PWordBool(data)^; |
2833 |
|
end; |
2878 |
|
FQRefresh.Transaction := Value; |
2879 |
|
FQSelect.Transaction := Value; |
2880 |
|
FQModify.Transaction := Value; |
2881 |
+ |
FGeneratorField.Transaction := Value; |
2882 |
|
end; |
2883 |
|
end; |
2884 |
|
|
4154 |
|
for i := 0 to SQLParams.GetCount - 1 do |
4155 |
|
begin |
4156 |
|
cur_field := DataSource.DataSet.FindField(SQLParams[i].Name); |
4157 |
< |
cur_param := SQLParams[i]; |
4158 |
< |
if (cur_field <> nil) then begin |
4157 |
> |
if (cur_field <> nil) then |
4158 |
> |
begin |
4159 |
> |
cur_param := SQLParams[i]; |
4160 |
|
if (cur_field.IsNull) then |
4161 |
|
cur_param.IsNull := True |
4162 |
< |
else case cur_field.DataType of |
4162 |
> |
else |
4163 |
> |
case cur_field.DataType of |
4164 |
|
ftString: |
4165 |
|
cur_param.AsString := cur_field.AsString; |
4166 |
|
ftBoolean: |
4170 |
|
ftInteger: |
4171 |
|
cur_param.AsLong := cur_field.AsInteger; |
4172 |
|
ftLargeInt: |
4173 |
< |
cur_param.AsInt64 := TLargeIntField(cur_field).AsLargeInt; |
4173 |
> |
cur_param.AsInt64 := cur_field.AsLargeInt; |
4174 |
|
ftFloat, ftCurrency: |
4175 |
|
cur_param.AsDouble := cur_field.AsFloat; |
4176 |
|
ftBCD: |
4924 |
|
function TIBCustomDataSet.GetFieldData(Field: TField; Buffer: Pointer; |
4925 |
|
NativeFormat: Boolean): Boolean; |
4926 |
|
begin |
4927 |
< |
if (Field.DataType = ftBCD) and not NativeFormat then |
4927 |
> |
{These datatypes use IBX conventions and not TDataset conventions} |
4928 |
> |
if (Field.DataType in [ftBCD,ftDateTime,ftDate,ftTime]) and not NativeFormat then |
4929 |
|
Result := InternalGetFieldData(Field, Buffer) |
4930 |
|
else |
4931 |
|
Result := inherited GetFieldData(Field, Buffer, NativeFormat); |
4951 |
|
procedure TIBCustomDataSet.SetFieldData(Field: TField; Buffer: Pointer; |
4952 |
|
NativeFormat: Boolean); |
4953 |
|
begin |
4954 |
< |
if (not NativeFormat) and (Field.DataType = ftBCD) then |
4954 |
> |
{These datatypes use IBX conventions and not TDataset conventions} |
4955 |
> |
if (not NativeFormat) and (Field.DataType in [ftBCD,ftDateTime,ftDate,ftTime]) then |
4956 |
|
InternalSetfieldData(Field, Buffer) |
4957 |
|
else |
4958 |
|
inherited SetFieldData(Field, buffer, NativeFormat); |
5056 |
|
|
5057 |
|
procedure TIBGenerator.SetIncrement(const AValue: integer); |
5058 |
|
begin |
5059 |
+ |
if FIncrement = AValue then Exit; |
5060 |
|
if AValue < 0 then |
5061 |
< |
raise Exception.Create('A Generator Increment cannot be negative'); |
5062 |
< |
FIncrement := AValue |
5061 |
> |
IBError(ibxeNegativeGenerator,[]); |
5062 |
> |
FIncrement := AValue; |
5063 |
> |
SetQuerySQL; |
5064 |
|
end; |
5065 |
|
|
5066 |
< |
function TIBGenerator.GetNextValue(ADatabase: TIBDatabase; |
5067 |
< |
ATransaction: TIBTransaction): integer; |
5066 |
> |
procedure TIBGenerator.SetTransaction(AValue: TIBTransaction); |
5067 |
|
begin |
5068 |
< |
with TIBSQL.Create(nil) do |
5069 |
< |
try |
5070 |
< |
Database := ADatabase; |
5071 |
< |
Transaction := ATransaction; |
5072 |
< |
if not assigned(Database) then |
5073 |
< |
IBError(ibxeCannotSetDatabase,[]); |
5074 |
< |
if not assigned(Transaction) then |
5075 |
< |
IBError(ibxeCannotSetTransaction,[]); |
5076 |
< |
with Transaction do |
5077 |
< |
if not InTransaction then StartTransaction; |
5078 |
< |
SQL.Text := Format('Select Gen_ID(%s,%d) as ID From RDB$Database',[FGeneratorName,Increment]); |
5079 |
< |
Prepare; |
5068 |
> |
FQuery.Transaction := AValue; |
5069 |
> |
end; |
5070 |
> |
|
5071 |
> |
procedure TIBGenerator.SetQuerySQL; |
5072 |
> |
begin |
5073 |
> |
FQuery.SQL.Text := Format('Select Gen_ID(%s,%d) From RDB$Database',[FGeneratorName,Increment]); |
5074 |
> |
end; |
5075 |
> |
|
5076 |
> |
function TIBGenerator.GetDatabase: TIBDatabase; |
5077 |
> |
begin |
5078 |
> |
Result := FQuery.Database; |
5079 |
> |
end; |
5080 |
> |
|
5081 |
> |
function TIBGenerator.GetTransaction: TIBTransaction; |
5082 |
> |
begin |
5083 |
> |
Result := FQuery.Transaction; |
5084 |
> |
end; |
5085 |
> |
|
5086 |
> |
procedure TIBGenerator.SetDatabase(AValue: TIBDatabase); |
5087 |
> |
begin |
5088 |
> |
FQuery.Database := AValue; |
5089 |
> |
end; |
5090 |
> |
|
5091 |
> |
procedure TIBGenerator.SetGeneratorName(AValue: string); |
5092 |
> |
begin |
5093 |
> |
if FGeneratorName = AValue then Exit; |
5094 |
> |
FGeneratorName := AValue; |
5095 |
> |
SetQuerySQL; |
5096 |
> |
end; |
5097 |
> |
|
5098 |
> |
function TIBGenerator.GetNextValue: integer; |
5099 |
> |
begin |
5100 |
> |
with FQuery do |
5101 |
> |
begin |
5102 |
> |
Transaction.Active := true; |
5103 |
|
ExecQuery; |
5104 |
|
try |
5105 |
< |
Result := FieldByName('ID').AsInteger |
5105 |
> |
Result := Fields[0].AsInteger |
5106 |
|
finally |
5107 |
|
Close |
5108 |
|
end; |
5087 |
– |
finally |
5088 |
– |
Free |
5109 |
|
end; |
5110 |
|
end; |
5111 |
|
|
5113 |
|
begin |
5114 |
|
FOwner := Owner; |
5115 |
|
FIncrement := 1; |
5116 |
+ |
FQuery := TIBSQL.Create(nil); |
5117 |
+ |
end; |
5118 |
+ |
|
5119 |
+ |
destructor TIBGenerator.Destroy; |
5120 |
+ |
begin |
5121 |
+ |
if assigned(FQuery) then FQuery.Free; |
5122 |
+ |
inherited Destroy; |
5123 |
|
end; |
5124 |
|
|
5125 |
|
|
5126 |
|
procedure TIBGenerator.Apply; |
5127 |
|
begin |
5128 |
< |
if (FGeneratorName <> '') and (FFieldName <> '') and Owner.FieldByName(FFieldName).IsNull then |
5129 |
< |
Owner.FieldByName(FFieldName).AsInteger := GetNextValue(Owner.Database,Owner.Transaction); |
5128 |
> |
if assigned(Database) and assigned(Transaction) and |
5129 |
> |
(FGeneratorName <> '') and (FFieldName <> '') and Owner.FieldByName(FFieldName).IsNull then |
5130 |
> |
Owner.FieldByName(FFieldName).AsInteger := GetNextValue; |
5131 |
|
end; |
5132 |
|
|
5133 |
|
|