ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/runtime/IBTable.pas
(Generate patch)

Comparing ibx/trunk/runtime/IBTable.pas (file contents):
Revision 5 by tony, Fri Feb 18 16:26:16 2011 UTC vs.
Revision 33 by tony, Sat Jul 18 12:30:52 2015 UTC

# Line 24 | Line 24
24   {       Corporation. All Rights Reserved.                                }
25   {    Contributor(s): Jeff Overcash                                       }
26   {                                                                        }
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                                                 }
31 + {                                                                        }
32   {************************************************************************}
33  
34   unit IBTable;
# Line 33 | Line 38 | unit IBTable;
38   interface
39  
40   uses SysUtils, Classes, DB, IB,  IBCustomDataSet,
41 <     IBHeader, IBSQL, IBUtils;
41 >     IBSQL, IBUtils;
42      
43   type
44  
# Line 142 | Line 147 | type
147      property TableNames: TStrings read GetTableNames;
148  
149    published
150 +    property AutoCommit;
151      property Active;
152      property BufferChunks;
153      property CachedUpdates;
154 <    property Constraints stored ConstraintsStored;
154 >    property DataSetCloseAction;
155 > //    property Constraints stored ConstraintsStored;
156      property DefaultIndex: Boolean read FDefaultIndex write FDefaultIndex default True;
157      property FieldDefs stored FieldDefsStored;
158      property Filter;
# Line 229 | Line 236 | begin
236        GenerateUpdateSQL;
237      FRegenerateSQL := False;
238    end;
239 + {  writeln(SelectSQL.Text);
240 +  writeln(InsertSQL.Text);
241 +  writeln(DeleteSQL.Text);
242 +  writeln(ModifySQL.Text); }
243    SetParams;
244    inherited InternalOpen;
245   end;
# Line 290 | Line 301 | end;
301  
302   procedure TIBTable.InitFieldDefs;
303   var
304 <  sqlscale: Integer;
304 >  DidActivate: Boolean;
305    Query: TIBSQL;
306   begin
307    if FTableName = '' then IBError(ibxeNoTableName, [nil]);
308 <  if (InternalPrepared) then InternalInitFieldDefs else
308 >  if (InternalPrepared) then
309 >     InternalInitFieldDefs
310 >  else
311    begin
312 <    Database.InternalTransaction.StartTransaction;
312 >    {Get the field defs from a simple query on the table}
313 >    ActivateConnection;
314      Query := TIBSQL.Create(self);
315      try
316 <      Query.GoToFirstRecordOnExecute := False;
317 <      Query.Database := DataBase;
318 <      Query.Transaction := Database.InternalTransaction;
319 <      Query.SQL.Text := 'Select R.RDB$FIELD_NAME, R.RDB$FIELD_POSITION, ' + {do not localize}
320 <                        'F.RDB$COMPUTED_BLR, F.RDB$DEFAULT_VALUE, ' + {do not localize}
321 <                        'F.RDB$NULL_FLAG, ' + {do not localize}
322 <                        'F.RDB$FIELD_LENGTH, F.RDB$FIELD_SCALE, ' + {do not localize}
309 <                        'F.RDB$FIELD_TYPE, F.RDB$FIELD_SUB_TYPE, ' + {do not localize}
310 <                        'F.RDB$EXTERNAL_LENGTH, F.RDB$EXTERNAL_SCALE, F.RDB$EXTERNAL_TYPE ' + {do not localize}
311 <                        'from RDB$RELATION_FIELDS R, RDB$FIELDS F ' + {do not localize}
312 <                        'where R.RDB$RELATION_NAME = ' + {do not localize}
313 <                        '''' +
314 <                        FormatIdentifierValue(Database.SQLDialect,
315 <                          QuoteIdentifier(DataBase.SQLDialect, FTableName)) +
316 <                        ''' ' +
317 <                        'and R.RDB$FIELD_SOURCE = F.RDB$FIELD_NAME '+ {do not localize}
318 <                        'order by R.RDB$FIELD_POSITION'; {do not localize}
319 <
320 <      Query.Prepare;
321 <      Query.ExecQuery;
322 <      FieldDefs.BeginUpdate;
323 <      FieldDefs.Clear;
324 <      while (not Query.EOF) and (Query.Next <> nil) do
325 <      begin
326 <          with FieldDefs.AddFieldDef do
327 <          begin
328 < (*           FieldNo := Query.Current.ByName('RDB$FIELD_POSITION').AsInteger; {do not localize}*)
329 <            Name := TrimRight(Query.Current.ByName('RDB$FIELD_NAME').AsString); {do not localize}
330 <            case Query.Current.ByName('RDB$FIELD_TYPE').AsInteger of {do not localize}
331 <              blr_varying, blr_text:
332 <              begin
333 <                DataType := ftString;
334 <                Size := Query.Current.ByName('RDB$FIELD_LENGTH').AsInteger; {do not localize}
335 <              end;
336 <              blr_float, blr_double, blr_d_float: DataType := ftFloat;
337 <              blr_short:
338 <              begin
339 <                sqlscale := Query.Current.ByName('RDB$FIELD_SCALE').AsInteger; {do not localize}
340 <                if (sqlscale = 0) then
341 <                  DataType := ftSmallInt
342 <                else
343 <                begin
344 <                  DataType := ftBCD;
345 <                  Precision := 4;
346 <                end;
347 <              end;
348 <              blr_long:
316 >         Query.Database := DataBase;
317 >         Query.Transaction := Database.InternalTransaction;
318 >         DidActivate := false;
319 >         Query.SQL.Text := 'Select * from ' + QuoteIdentifier(DataBase.SQLDialect, FTableName);
320 >         with Query.Transaction do
321 >         begin
322 >              if not InTransaction then
323                begin
324 <                sqlscale := Query.Current.ByName('RDB$FIELD_SCALE').AsInteger; {do not localize}
325 <                if (sqlscale = 0) then
352 <                  DataType := ftInteger
353 <                else if (sqlscale >= (-4)) then
354 <                begin
355 <                  DataType := ftBCD;
356 <                  Precision := 9;
357 <                end
358 <                else
359 <                  DataType := ftFloat;
324 >                StartTransaction;
325 >                DidActivate := true
326                end;
327 <              blr_int64:
328 <              begin
329 <                sqlscale := Query.Current.ByName('RDB$FIELD_SCALE').AsInteger; {do not localize}
330 <                if (sqlscale = 0) then
331 <                  DataType := ftLargeInt
366 <                else if (sqlscale >= (-4)) then
367 <                begin
368 <                  DataType := ftBCD;
369 <                  Precision := 18;
370 <                end
371 <                else
372 <                  DataType := ftFloat;
373 <              end;
374 <              blr_timestamp: DataType := ftDateTime;
375 <              blr_sql_time: DataType := ftTime;
376 <              blr_sql_date: DataType := ftDate;
377 <              blr_blob:
378 <                if (Query.Current.ByName('RDB$FIELD_SUB_TYPE').AsInteger = 1) then {do not localize}
379 <                  DataType := ftMemo
380 <                else
381 <                  DataType := ftBlob;
382 <              blr_quad:
383 <              begin
384 <                DataType := ftUnknown;
385 <                Size := sizeof (TISC_QUAD);
386 <              end;
387 <              else
388 <                DataType := ftUnknown;
389 <            end;
390 <            if not (Query.Current.ByName('RDB$COMPUTED_BLR').IsNull) then {do not localize}
391 <            begin
392 <              Attributes := [faReadOnly];
393 <              InternalCalcField := True
394 <            end
395 <            else
396 <              InternalCalcField := False;
397 <            if ((not InternalCalcField) and
398 <                 Query.Current.ByName('RDB$DEFAULT_VALUE').IsNull and {do not localize}
399 <                 (Query.Current.ByName('RDB$NULL_FLAG').AsInteger = 1) )then {do not localize}
400 <            begin
401 <              Attributes := [faRequired];
402 <              Required := True;
403 <            end;
404 <          end;
405 <      end;
406 <      FieldDefs.EndUpdate;
327 >         end;
328 >         Query.Prepare;
329 >         if DidActivate then
330 >            Query.Transaction.Rollback;
331 >         FieldDefsFromQuery(Query);
332      finally
333 <      Query.free;
409 <      Database.InternalTransaction.Commit;
333 >         Query.Free;
334      end;
335    end;
336   end;
# Line 640 | Line 564 | var
564    Opts: TIndexOptions;
565    Flds: string;
566    Query, SubQuery: TIBSQL;
567 +  fn: string;
568 +  aField: TFieldDef;
569   begin
570    if not (csReading in ComponentState) then begin
571    if not Active and not FSwitchingIndex  then
# Line 672 | Line 598 | begin
598          if Query.Current.ByName('RDB$INDEX_TYPE').AsInteger = 2  then Include(Opts, ixDescending); {do not localize}
599          Options := Opts;
600          if (Query.Current.ByName('RDB$SEGMENT_COUNT').AsInteger = 1) then {do not localize}
601 <          Fields := Trim(Query.Current.ByName('RDB$FIELD_NAME').AsString) {do not localize}
601 >        begin
602 >          fn := Trim(Query.Current.ByName('RDB$FIELD_NAME').AsString); {do not localize}
603 >          aField := GetFieldDefFromAlias(fn);
604 >          if assigned(aField) then
605 >             Fields := aField.Name
606 >          else
607 >              Fields := fn;
608 >        end
609          else begin
610            SubQuery := TIBSQL.Create(self);
611          try
# Line 690 | Line 623 | begin
623            Flds := '';
624            while (not SubQuery.EOF) and (SubQuery.Next <> nil) do
625            begin
626 +            fn := TrimRight(SubQuery.Current.ByName('RDB$FIELD_NAME').AsString); {do not localize}
627 +            aField := GetFieldDefFromAlias(fn);
628 +            if assigned(aField) then
629 +               fn := aField.Name;
630              if (Flds = '') then
631 <              Flds := TrimRight(SubQuery.Current.ByName('RDB$FIELD_NAME').AsString) {do not localize}
631 >               Flds := fn
632              else begin
633                Query.Next;
634 <              Flds := Flds + ';' + TrimRight(SubQuery.Current[0].AsString);
634 >              Flds := Flds + ';' + fn;
635              end;
636            end;
637            Fields := Flds;
# Line 778 | Line 715 | var
715              FieldList := FieldList +
716                QuoteIdentifier(DataBase.SQLDialect, Name) +
717                ' CHAR(' + IntToStr(Size) + ')'; {do not localize}
718 <          ftBoolean, ftSmallint, ftWord:
718 >          ftBoolean:
719 >            FieldList := FieldList +
720 >              QuoteIdentifier(DataBase.SQLDialect, Name) +
721 >              ' BOOLEAN'; {do not localize}
722 >          ftSmallint, ftWord:
723              FieldList := FieldList +
724                QuoteIdentifier(DataBase.SQLDialect, Name) +
725                ' SMALLINT'; {do not localize}
# Line 1294 | Line 1235 | var
1235    SQL: TStrings;
1236    OrderByStr: string;
1237    bWhereClausePresent: Boolean;
1238 +  fn: string;
1239 +  aField: TFieldDef;
1240   begin
1241    bWhereClausePresent := False;
1242    Database.CheckActive;
# Line 1329 | Line 1272 | begin
1272      begin
1273        if i > 0 then
1274          SQL.Text := SQL.Text + 'AND ';
1275 +      aField := FieldDefs.Find(FDetailFieldsList.Strings[i]);
1276 +      if assigned(aField) then
1277 +         fn := GetDBAliasName(aField.FieldNo)
1278 +      else
1279 +          fn := FDetailFieldsList.Strings[i]; {something wrong if we get here - but should word}
1280        SQL.Text := SQL.Text +
1281 <        QuoteIdentifier(DataBase.SQLDialect, FDetailFieldsList.Strings[i]) +
1334 <        ' = :' +
1335 <        QuoteIdentifier(DataBase.SQLDialect, FMasterFieldsList.Strings[i]);
1281 >        QuoteIdentifier(DataBase.SQLDialect, fn) + ' = :' + FMasterFieldsList.Strings[i];
1282      end;
1283    end;
1284    if OrderByStr <> '' then
# Line 1370 | Line 1316 | var
1316                WhereAllFieldList := WhereAllFieldList + ' AND ';
1317            end;
1318            InsertFieldList := InsertFieldList +
1319 <            QuoteIdentifier(DataBase.SQLDialect, Name);
1320 <          InsertParamList := InsertParamList + ':' +
1375 <            QuoteIdentifier(DataBase.SQLDialect, Name);
1319 >            QuoteIdentifier(DataBase.SQLDialect, GetDBAliasName(FieldNo));
1320 >          InsertParamList := InsertParamList + ':' +  Name;
1321            UpdateFieldList := UpdateFieldList +
1322 <            QuoteIdentifier(DataBase.SQLDialect, Name) +
1323 <            ' = :' +
1379 <            QuoteIdentifier(DataBase.SQLDialect, Name);
1322 >            QuoteIdentifier(DataBase.SQLDialect, GetDBAliasName(FieldNo)) +
1323 >            ' = :' + Name;
1324            if (DataType <> ftBlob) and (DataType <>ftMemo) then
1325              WhereAllFieldList := WhereAllFieldList +
1326 <              QuoteIdentifier(DataBase.SQLDialect, Name) + ' = :' +
1383 <              QuoteIdentifier(DataBase.SQLDialect, Name);{do not localize}
1326 >              QuoteIdentifier(DataBase.SQLDialect, GetDBAliasName(FieldNo)) + ' = :' +  Name;
1327          end;
1328        end;
1329      end;
# Line 1389 | Line 1332 | var
1332    procedure GenerateWherePrimaryFieldList;
1333    var
1334      i: Integer;
1335 <    tmp: String;
1335 >    tmp, fn: String;
1336 >    aField: TFieldDef;
1337    begin
1338      i := 1;
1339      while i <= Length(FPrimaryIndexFields) do
1340      begin
1341        tmp := ExtractFieldName(FPrimaryIndexFields, i);
1342 +      aField := FieldDefs.Find(tmp);
1343 +      if assigned(aField) then
1344 +         fn := GetDBAliasName(aField.FieldNo)
1345 +      else
1346 +         fn := tmp; {something wrong if we get here - but will work in most cases}
1347        tmp :=
1348 <        QuoteIdentifier(DataBase.SQLDialect, tmp) +  ' = :' +
1348 >        QuoteIdentifier(DataBase.SQLDialect, fn) +  ' = :' +
1349          QuoteIdentifier(DataBase.SQLDialect, tmp);{do not localize}
1350        if WherePrimaryFieldList <> '' then
1351          WherePrimaryFieldList :=

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines