TUpdateSQL.Query equivalent in TUniUpdateSQL?

Discussion of open issues, suggestions and bugs regarding UniDAC (Universal Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
kamiller42
Posts: 40
Joined: Thu 27 Jan 2011 22:31

TUpdateSQL.Query equivalent in TUniUpdateSQL?

Post by kamiller42 » Fri 30 Mar 2012 03:31

I am converting a project from IBX to Unidac. One feature of TUpdateSQL and TIBUpdateSQL was the ability to reference the internal query object used to perform CRUD.

The wizard did a good job converting the components. It created uniquery and uniupdatesql components appropriately. Now I need to convert code that looks like this...

lDS := updClientAttribute.Query[ukDelete];
if not lDS.Transaction.Active then
lDS.Transaction.StartTransaction;

I don't have Uni source. Otherwise, I would see if the update SQL component sets up any objects internally to accomplish executing the assigned SQL statements.

AndreyZ

Post by AndreyZ » Tue 03 Apr 2012 13:23

You can use the following code:

Code: Select all

procedure TMainForm.BitBtnClick(Sender: TObject);
var
  lDS: TUniQuery;
  tr: TUniTransaction;
begin
  lDS := UniUpdateSQL1.DeleteObject as TUniQuery;
  if lDS  nil then begin
    if lDS.UpdateTransaction  nil then
      tr := lDS.UpdateTransaction
    else
      tr := lDS.Transaction;
    if tr  nil then begin // if transaction is specifed in TUniQuery
      if not tr.Active then
        tr.StartTransaction;
    end
    else
    begin // else default transaction is used
      if not lDS.Connection.InTransaction then
        lDS.Connection.StartTransaction;
    end;
  end;
end;

kamiller42
Posts: 40
Joined: Thu 27 Jan 2011 22:31

Post by kamiller42 » Tue 03 Apr 2012 16:03

Thanks for the code Andrey. The problem is the TUniUpdateSQL is a component whose primary existence is to provide compatibility with similar components in other DB engines, like BDE and IBX. TUniQuery is powerful enough to not need TUniUpdateSQL.

With this mind, TUniUpdateSQL appears in conversion projects where the DeleteObject, etc. will not be assigned. That's the case with my converted IBX project. Your code will never fire because the hundreds of UniUpdateSQL components do not have the objects assigned. With BDE and IBX, those object properties were not needed because they managed a list internally and created CRUD objects on demand.

Here is IBX's code...

Code: Select all

function TIBUpdateSQL.GetQuery(UpdateKind: TUpdateKind): TIBQuery;
begin
  if not Assigned(FQueries[UpdateKind]) then
  begin
    FQueries[UpdateKind] := TIBQuery.Create(Self);
    FQueries[UpdateKind].SQL.Assign(FSQLText[UpdateKind]);
    if (FDataSet is TIBCustomDataSet) then
    begin
      FQueries[UpdateKind].Database := TIBCustomDataSet(FDataSet).DataBase;
      FQueries[UpdateKind].Transaction := TIBCustomDataSet(FDataSet).Transaction;
    end;
  end;
  Result := FQueries[UpdateKind];
end;
Does UniUpdateSQL create its own update objects if the user has not assigned the properties? It must do something similar to the code above even if it isn't a published property.

I am thinking I might have to descend from TUniUpdateSql and add a Query property with a getter and setter. The setter will of course just assign the appropriate XyzObject property and the getter will create an object on the fly like IBX above. Then, I will have to replace all TUniUpdateSqls with my component.

Is there a better solution?

AndreyZ

Post by AndreyZ » Wed 04 Apr 2012 11:46

TUniUpdateSQL doesn't create new objects, you should provide them to it. In you want to obtain the exact functionality with UniDAC as with IBX, the only solution is the one you described. You should create your own class inherited from TUniUpdateSQL and implement all needed functionality yourself.

Post Reply