djjd47130

Data Pump

Jan 1st, 2013
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 26.89 KB | None | 0 0
  1. unit uDataPump;
  2.  
  3. interface
  4.  
  5. uses
  6.   Winapi.Windows, Winapi.Messages,
  7.   System.SysUtils, System.Variants, System.Classes,
  8.   Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  9.   DB, ADODB, Clipbrd,
  10.   Inno.Dataset, Inno.Common, IniFiles;
  11.  
  12. type
  13.   TDatabase = class;
  14.   TDatabases = class;
  15.   TDataPump = class;
  16.   TFieldLink = class;
  17.   TFieldLinks = class;
  18.  
  19.   TFieldLinkType = (flText, flInt, flFloat, flLookup);
  20.  
  21.   TConnectedEvent = procedure(Sender: TObject; const Connected: Boolean) of object;
  22.  
  23.   TDatabase = class(TObject)
  24.   private
  25.     FCaption: String;
  26.     FConnectionString: String;
  27.     FActive: Boolean;
  28.     FSchema: String;
  29.     FShortCaption: String;
  30.     procedure SetCaption(const Value: String);
  31.     procedure SetActive(const Value: Boolean);
  32.     procedure SetConnectionString(const Value: String);
  33.     procedure SetSchema(const Value: String);
  34.     procedure SetShortCaption(const Value: String);
  35.   public
  36.     constructor Create;
  37.     destructor Destroy; override;
  38.     property Caption: String read FCaption write SetCaption;
  39.     property ShortCaption: String read FShortCaption write SetShortCaption;
  40.     property ConnectionString: String
  41.       read FConnectionString write SetConnectionString;
  42.     property Schema: String read FSchema write SetSchema;
  43.     property Active: Boolean read FActive write SetActive;
  44.   end;
  45.  
  46.   TDatabases = class(TPersistent)
  47.   private
  48.     FOwner: TDataPump;
  49.     FItems: TStringList;
  50.     function GetItem(Index: Integer): TDatabase;
  51.     procedure SetItem(Index: Integer; const Value: TDatabase);
  52.   public
  53.     constructor Create(AOwner: TDataPump);
  54.     destructor Destroy; override;
  55.     function Add: TDatabase;
  56.     procedure Delete(const Index: Integer);
  57.     function IndexOf(ADatabase: TDatabase): Integer;
  58.     procedure Clear;
  59.     function Count: Integer;
  60.     property Databases[Index: Integer]: TDatabase
  61.       read GetItem write SetItem; default;
  62.   end;
  63.  
  64.   TFieldLink = class(TPersistent)
  65.   private
  66.     FFieldName: String;
  67.     FInsertSQL: String;
  68.     FDeleteSQL: String;
  69.     FUpdateSQL: String;
  70.     FSelectSQL: String;
  71.     FIsIdentity: Boolean;
  72.     FPrimaryKey: Boolean;
  73.     FIsReadOnly: Boolean;
  74.     FCanCreate: Boolean;
  75.     FLinkType: TFieldLinkType;
  76.     FLookupTable: String;
  77.     FLookupField: String;
  78.     FLookupValue: String;
  79.     FName: String;
  80.     FAlias: String;
  81.     procedure SetFieldName(const Value: String);
  82.     procedure SetInsertSQL(const Value: String);
  83.     procedure SetDeleteSQL(const Value: String);
  84.     procedure SetSelectSQL(const Value: String);
  85.     procedure SetUpdateSQL(const Value: String);
  86.     procedure SetIsIdentity(const Value: Boolean);
  87.     procedure SetIsReadOnly(const Value: Boolean);
  88.     procedure SetPrimaryKey(const Value: Boolean);
  89.     procedure SetLinkType(const Value: TFieldLinkType);
  90.     procedure SetLookupField(const Value: String);
  91.     procedure SetLookupTable(const Value: String);
  92.     procedure SetLookupValue(const Value: String);
  93.     procedure SetName(const Value: String);
  94.     procedure SetCanCreate(const Value: Boolean);
  95.     procedure SetAlias(const Value: String);
  96.   public
  97.     constructor Create;
  98.     destructor Destroy; override;
  99.   published
  100.     property FieldName: String read FFieldName write SetFieldName;
  101.     property Name: String read FName write SetName;
  102.     property Alias: String read FAlias write SetAlias;
  103.     property LinkType: TFieldLinkType read FLinkType write SetLinkType;
  104.     property InsertSQL: String read FInsertSQL write SetInsertSQL;
  105.     property UpdateSQL: String read FUpdateSQL write SetUpdateSQL;
  106.     property DeleteSQL: String read FDeleteSQL write SetDeleteSQL;
  107.     property SelectSQL: String read FSelectSQL write SetSelectSQL;
  108.     property PrimaryKey: Boolean read FPrimaryKey write SetPrimaryKey;
  109.     property IsIdentity: Boolean read FIsIdentity write SetIsIdentity;
  110.     property IsReadOnly: Boolean read FIsReadOnly write SetIsReadOnly;
  111.     property CanCreate: Boolean read FCanCreate write SetCanCreate;
  112.     property LookupTable: String read FLookupTable write SetLookupTable;
  113.     property LookupField: String read FLookupField write SetLookupField;
  114.     property LookupValue: String read FLookupValue write SetLookupValue;
  115.   end;
  116.  
  117.   TFieldLinks = class(TPersistent)
  118.   private
  119.     FItems: TList;
  120.     FJoins: TStringList;
  121.     FMatch: TStringList;
  122.     FSourceTable: String;
  123.     FSourceID: String;
  124.     FSourceCaption: String;
  125.     FSourceAlias: String;
  126.     function GetItem(Index: Integer): TFieldLink;
  127.     procedure SetItem(Index: Integer; const Value: TFieldLink);
  128.     function GetJoins: TStrings;
  129.     procedure SetJoins(const Value: TStrings);
  130.     procedure SetSourceTable(const Value: String);
  131.     procedure SetSourceCaption(const Value: String);
  132.     procedure SetSourceID(const Value: String);
  133.     function GetMatch: TStrings;
  134.     procedure SetMatch(const Value: TStrings);
  135.     procedure SetSourceAlias(const Value: String);
  136.   public
  137.     constructor Create;
  138.     destructor Destroy; override;
  139.     function Add: TFieldLink; overload;
  140.     function Add(const FieldName: String): TFieldLink; overload;
  141.     procedure Delete(const Index: Integer);
  142.     procedure Clear;
  143.     function Count: Integer;
  144.     property Items[Index: Integer]: TFieldLink
  145.       read GetItem write SetItem; default;
  146.     procedure LoadFromFile(const Filename: String);
  147.     procedure SaveToFile(const Filename: String);
  148.     property Joins: TStrings read GetJoins write SetJoins;
  149.     property Match: TStrings read GetMatch write SetMatch;
  150.     property SourceTable: String read FSourceTable write SetSourceTable;
  151.     property SourceID: String read FSourceID write SetSourceID;
  152.     property SourceCaption: String read FSourceCaption write SetSourceCaption;
  153.     property SourceAlias: String read FSourceAlias write SetSourceAlias;
  154.     function FieldByName(const Name: String): TFieldLink;
  155.   end;
  156.  
  157.   TDataPump = class(TPersistent)
  158.   private
  159.     FDatabases: TDatabases;
  160.     FSourceDB: TADOConnection;
  161.     FDestDB: TADOConnection;
  162.     FDestIndex: Integer;
  163.     FSourceIndex: Integer;
  164.     FSourceLinks: TFieldLinks;
  165.     FDestLinks: TFieldLinks;
  166.     FSourceData: TInnoDataset;
  167.     FDestData: TInnoDataset;
  168.     FActive: Boolean;
  169.     FTempQry: TADOQuery;
  170.     FWhereSQL: TStringList;
  171.     FOnConnect: TConnectedEvent;
  172.     function ImportField(ASource: TFieldLink; const Value: String): Integer;
  173.     procedure DBConnected(Sender: TObject);
  174.     procedure DBDisconnected(Sender: TObject);
  175.     procedure DoOnConnect(const Connected: Boolean);
  176.     procedure SetDestIndex(const Value: Integer);
  177.     procedure SetSourceIndex(const Value: Integer);
  178.     procedure SetActive(const Value: Boolean);
  179.     function GetWhereSQL: TStrings;
  180.     procedure SetWhereSQL(const Value: TStrings);
  181.     function ReplaceSQL(AFieldLinks: TFieldLinks; ADataset: TInnoDataset;
  182.       const SQL: String): String;
  183.   public
  184.     constructor Create;
  185.     destructor Destroy; override;
  186.     function Filename: String;
  187.     procedure LoadFromFile;
  188.     procedure SaveToFile;
  189.     function SourceDB: TADOConnection;
  190.     function SourceConn: TDatabase;
  191.     function SourceNewQuery: TADOQuery;
  192.     function DestDB: TADOConnection;
  193.     function DestConn: TDatabase;
  194.     function DestNewQuery: TADOQuery;
  195.     function SchemaDir: String;
  196.     procedure PushData;
  197.     function LookupID(ALink: TFieldLink; const Value: String): Integer;
  198.     function GetSourceSQL: String;
  199.   published
  200.     property Active: Boolean read FActive write SetActive;
  201.     property Databases: TDatabases read FDatabases;
  202.     property SourceIndex: Integer read FSourceIndex write SetSourceIndex;
  203.     property DestIndex: Integer read FDestIndex write SetDestIndex;
  204.     property WhereSQL: TStrings read GetWhereSQL write SetWhereSQL;
  205.     property OnConnect: TConnectedEvent read FOnConnect write FOnConnect;
  206.   end;
  207.  
  208. implementation
  209.  
  210. { TDatabases }
  211.  
  212. constructor TDatabases.Create(AOwner: TDataPump);
  213. begin
  214.   FOwner:= AOwner;
  215.   FItems:= TStringList.Create;
  216. end;
  217.  
  218. destructor TDatabases.Destroy;
  219. begin
  220.   Clear;
  221.   FItems.Free;
  222.   inherited;
  223. end;
  224.  
  225. function TDatabases.Add: TDatabase;
  226. begin
  227.   Result:= TDatabase.Create;
  228.   FItems.AddObject('', Result);
  229. end;
  230.  
  231. procedure TDatabases.Clear;
  232. begin
  233.   while Count > 0 do
  234.     Delete(0);
  235. end;
  236.  
  237. function TDatabases.Count: Integer;
  238. begin
  239.   Result:= FItems.Count;
  240. end;
  241.  
  242. procedure TDatabases.Delete(const Index: Integer);
  243. begin
  244.   TDatabase(FItems.Objects[Index]).Free;
  245.   FItems.Delete(Index);
  246. end;
  247.  
  248. function TDatabases.GetItem(Index: Integer): TDatabase;
  249. begin
  250.   Result:= TDatabase(FItems.Objects[Index]);
  251. end;
  252.  
  253. function TDatabases.IndexOf(ADatabase: TDatabase): Integer;
  254. begin
  255.   Result:= FItems.IndexOfObject(ADatabase);
  256. end;
  257.  
  258. procedure TDatabases.SetItem(Index: Integer; const Value: TDatabase);
  259. begin
  260.   FItems.Objects[Index]:= Value;
  261. end;
  262.  
  263. { TDatabase }
  264.  
  265. constructor TDatabase.Create;
  266. begin
  267.  
  268. end;
  269.  
  270. destructor TDatabase.Destroy;
  271. begin
  272.  
  273.   inherited;
  274. end;
  275.  
  276. procedure TDatabase.SetActive(const Value: Boolean);
  277. begin
  278.   FActive := Value;
  279. end;
  280.  
  281. procedure TDatabase.SetCaption(const Value: String);
  282. begin
  283.   FCaption := Value;
  284. end;
  285.  
  286. procedure TDatabase.SetConnectionString(const Value: String);
  287. begin
  288.   FConnectionString := Value;
  289. end;
  290.  
  291. procedure TDatabase.SetSchema(const Value: String);
  292. begin
  293.   FSchema := Value;
  294. end;
  295.  
  296. procedure TDatabase.SetShortCaption(const Value: String);
  297. begin
  298.   FShortCaption := Value;
  299. end;
  300.  
  301. { TFieldLink }
  302.  
  303. constructor TFieldLink.Create;
  304. begin
  305.  
  306. end;
  307.  
  308. destructor TFieldLink.Destroy;
  309. begin
  310.  
  311.   inherited;
  312. end;
  313.  
  314. procedure TFieldLink.SetAlias(const Value: String);
  315. begin
  316.   FAlias := Value;
  317. end;
  318.  
  319. procedure TFieldLink.SetCanCreate(const Value: Boolean);
  320. begin
  321.   FCanCreate := Value;
  322. end;
  323.  
  324. procedure TFieldLink.SetDeleteSQL(const Value: String);
  325. begin
  326.   FDeleteSQL := Value;
  327. end;
  328.  
  329. procedure TFieldLink.SetFieldName(const Value: String);
  330. begin
  331.   FFieldName := Value;
  332. end;
  333.  
  334. procedure TFieldLink.SetInsertSQL(const Value: String);
  335. begin
  336.   FInsertSQL := Value;
  337. end;
  338.  
  339. procedure TFieldLink.SetIsIdentity(const Value: Boolean);
  340. begin
  341.   FIsIdentity := Value;
  342. end;
  343.  
  344. procedure TFieldLink.SetIsReadOnly(const Value: Boolean);
  345. begin
  346.   FIsReadOnly := Value;
  347. end;
  348.  
  349. procedure TFieldLink.SetLinkType(const Value: TFieldLinkType);
  350. begin
  351.   FLinkType := Value;
  352. end;
  353.  
  354. procedure TFieldLink.SetLookupField(const Value: String);
  355. begin
  356.   FLookupField := Value;
  357. end;
  358.  
  359. procedure TFieldLink.SetLookupTable(const Value: String);
  360. begin
  361.   FLookupTable := Value;
  362. end;
  363.  
  364. procedure TFieldLink.SetLookupValue(const Value: String);
  365. begin
  366.   FLookupValue := Value;
  367. end;
  368.  
  369. procedure TFieldLink.SetName(const Value: String);
  370. begin
  371.   FName := Value;
  372. end;
  373.  
  374. procedure TFieldLink.SetPrimaryKey(const Value: Boolean);
  375. begin
  376.   FPrimaryKey := Value;
  377. end;
  378.  
  379. procedure TFieldLink.SetSelectSQL(const Value: String);
  380. begin
  381.   FSelectSQL := Value;
  382. end;
  383.  
  384. procedure TFieldLink.SetUpdateSQL(const Value: String);
  385. begin
  386.   FUpdateSQL := Value;
  387. end;
  388.  
  389. { TFieldLinks }
  390.  
  391. constructor TFieldLinks.Create;
  392. begin
  393.   FItems:= TList.Create;
  394.   FJoins:= TStringList.Create;
  395.   FMatch:= TStringList.Create;
  396. end;
  397.  
  398. destructor TFieldLinks.Destroy;
  399. begin
  400.   Clear;
  401.   FMatch.Free;
  402.   FJoins.Free;
  403.   FItems.Free;
  404.   inherited;
  405. end;
  406.  
  407. function TFieldLinks.FieldByName(const Name: String): TFieldLink;
  408. var
  409.   X: Integer;
  410.   L: TFieldLink;
  411. begin
  412.   Result:= nil;
  413.   for X := 0 to FItems.Count - 1 do begin
  414.     L:= TFieldLink(FItems[X]);
  415.     if UpperCase(L.FName) = UpperCase(Name) then begin
  416.       Result:= L;
  417.       Break;
  418.     end;
  419.   end;
  420. end;
  421.  
  422. function TFieldLinks.Add: TFieldLink;
  423. begin
  424.   Result:= TFieldLink.Create;
  425.   FItems.Add(Result);
  426. end;
  427.  
  428. function TFieldLinks.Add(const FieldName: String): TFieldLink;
  429. begin
  430.   Result:= Add;
  431.   Result.FieldName:= FieldName;
  432. end;
  433.  
  434. procedure TFieldLinks.Clear;
  435. begin
  436.   while Count > 0 do
  437.     Delete(0);
  438.   FJoins.Clear;
  439.   FMatch.Clear;
  440. end;
  441.  
  442. function TFieldLinks.Count: Integer;
  443. begin
  444.   Result:= FItems.Count;
  445. end;
  446.  
  447. procedure TFieldLinks.Delete(const Index: Integer);
  448. begin
  449.   TFieldLink(FItems[Index]).Free;
  450.   FItems.Delete(Index);
  451. end;
  452.  
  453. function TFieldLinks.GetItem(Index: Integer): TFieldLink;
  454. begin
  455.   Result:= TFieldLink(FItems[Index]);
  456. end;
  457.  
  458. procedure TFieldLinks.SetItem(Index: Integer; const Value: TFieldLink);
  459. begin
  460.   FItems[Index]:= Value;
  461. end;
  462.  
  463. function TFieldLinks.GetJoins: TStrings;
  464. begin
  465.   Result:= TStrings(FJoins);
  466. end;
  467.  
  468. function TFieldLinks.GetMatch: TStrings;
  469. begin
  470.   Result:= TStrings(FMatch);
  471. end;
  472.  
  473. procedure TFieldLinks.SetJoins(const Value: TStrings);
  474. begin
  475.   FJoins.Assign(Value);
  476. end;
  477.  
  478. procedure TFieldLinks.SetMatch(const Value: TStrings);
  479. begin
  480.   FMatch.Assign(Value);
  481. end;
  482.  
  483. procedure TFieldLinks.SetSourceAlias(const Value: String);
  484. begin
  485.   FSourceAlias := Value;
  486. end;
  487.  
  488. procedure TFieldLinks.SetSourceCaption(const Value: String);
  489. begin
  490.   FSourceCaption := Value;
  491. end;
  492.  
  493. procedure TFieldLinks.SetSourceID(const Value: String);
  494. begin
  495.   FSourceID := Value;
  496. end;
  497.  
  498. procedure TFieldLinks.SetSourceTable(const Value: String);
  499. begin
  500.   FSourceTable := Value;
  501. end;
  502.  
  503. procedure TFieldLinks.LoadFromFile(const Filename: String);
  504. var
  505.   I: TIniFile;
  506.   L: TStringList;
  507.   FL: TFieldLink;
  508.   X: Integer;
  509.   T: String;
  510. begin
  511.   Clear;
  512.   if FileExists(Filename) then begin
  513.     I:= TIniFile.Create(Filename);
  514.     try
  515.       L:= TStringList.Create;
  516.       try
  517.         FSourceTable:= I.ReadString('table', 'tbl', '');
  518.         FSourceID:= I.ReadString('table', 'id', '');
  519.         FSourceCaption:= I.ReadString('table', 'caption', '');
  520.         FSourceAlias:= I.ReadString('table', 'alias', 'Source');
  521.         I.ReadSection('joins', L);
  522.         for X := 0 to L.Count - 1 do
  523.           FJoins.Append(I.ReadString('joins', L[X], ''));
  524.         I.ReadSection('match', L);
  525.         for X := 0 to L.Count - 1 do
  526.           FMatch.Append(I.ReadString('match', L[X], ''));
  527.         I.ReadSections(L);
  528.         for X := 0 to L.Count - 1 do begin
  529.           if StrToIntDef(L[X], -1) >= 0 then begin
  530.             FL:= Add;
  531.             FL.FieldName:= I.ReadString(L[X], 'fld', '');
  532.             FL.Name:= I.ReadString(L[X], 'nam', FL.FieldName);
  533.             FL.Alias:= I.ReadString(L[X], 'alias', '');
  534.             FL.InsertSQL:= I.ReadString(L[X], 'ins', '');
  535.             FL.UpdateSQL:= I.ReadString(L[X], 'upd', '');
  536.             FL.DeleteSQL:= I.ReadString(L[X], 'del', '');
  537.             FL.SelectSQL:= I.ReadString(L[X], 'sel', '');
  538.             FL.FPrimaryKey:= UpperCase(I.ReadString(L[X], 'prk', '')) = 'Y';
  539.             FL.FIsIdentity:= UpperCase(I.ReadString(L[X], 'idt', '')) = 'Y';
  540.             FL.FIsReadOnly:= UpperCase(I.ReadString(L[X], 'rdo', '')) = 'Y';
  541.             FL.FCanCreate:= UpperCase(I.ReadString(L[X], 'new', '')) = 'Y';
  542.             FL.LookupTable:= I.ReadString(L[X], 'tbl', '');
  543.             FL.LookupField:= I.ReadString(L[X], 'lnk', '');
  544.             FL.LookupValue:= I.ReadString(L[X], 'val', '');
  545.             T:= LowerCase(I.ReadString(L[X], 'typ', 'text'));
  546.             if T = 'text' then
  547.               FL.FLinkType:= flText
  548.             else if T = 'int' then
  549.               FL.FLinkType:= flInt
  550.             else if T = 'float' then
  551.               FL.FLinkType:= flFloat
  552.             else if T = 'lookup' then
  553.               FL.FLinkType:= flLookup
  554.             else FL.FLinkType:= flText;
  555.           end;
  556.         end;
  557.       finally
  558.         L.Free;
  559.       end;
  560.     finally
  561.       I.Free;
  562.     end;
  563.   end else begin
  564.     raise Exception.Create('Schema file does not exist "'+Filename+'"');
  565.   end;
  566. end;
  567.  
  568. procedure TFieldLinks.SaveToFile(const Filename: String);
  569. begin
  570.  
  571. end;
  572.  
  573. { TDataPump }
  574.  
  575. constructor TDataPump.Create;
  576. begin
  577.   FDatabases:= TDatabases.Create(Self);
  578.   FSourceLinks:= TFieldLinks.Create;
  579.   FDestLinks:= TFieldLinks.Create;
  580.   FWhereSQL:= TStringList.Create;
  581.   FSourceDB:= TADOConnection.Create(nil);
  582.   FDestDB:= TADOConnection.Create(nil);
  583.   FSourceDB.LoginPrompt:= False;
  584.   FDestDB.LoginPrompt:= False;
  585.   FSourceData:= TInnoDataset.Create(nil);
  586.   FDestData:= TInnoDataset.Create(nil);
  587.   FSourceIndex:= -1;
  588.   FDestIndex:= -1;
  589.   FSourceDB.AfterConnect:= DBConnected;
  590.   FDestDB.AfterConnect:= DBConnected;
  591.   FSourceDB.AfterDisconnect:= DBDisconnected;
  592.   FDestDB.AfterDisconnect:= DBDisconnected;
  593.   FTempQry:= DestNewQuery;
  594. end;
  595.  
  596. destructor TDataPump.Destroy;
  597. begin
  598.   FTempQry.Free;
  599.   FSourceData.Free;
  600.   FDestData.Free;
  601.   FSourceDB.Free;
  602.   FDestDB.Free;
  603.   FSourceLinks.Free;
  604.   FDestLinks.Free;
  605.   FDatabases.Free;
  606.   FWhereSQL.Free;
  607.   inherited;
  608. end;
  609.  
  610. function TDataPump.GetSourceSQL: String;
  611. var
  612.   X: Integer;
  613.   L: TFieldLink;
  614.   J: TStringList;
  615.   AL: String;
  616.   S: String;
  617.   T: String;
  618.   procedure A(const Text: String);
  619.   begin
  620.     Result:= Result + Text + sLineBreak;
  621.   end;
  622. begin
  623.   J:= TStringList.Create;
  624.   try
  625.     A('select');
  626.     for X := 0 to FSourceLinks.Count - 1 do begin
  627.       L:= FSourceLinks[X];
  628.       case L.FLinkType of
  629.         flText, flInt, flFloat: begin
  630.           S:= FSourceLinks.FSourceAlias+'.'+L.FFieldName+' as '''+L.FName+'''';
  631.         end;
  632.         flLookup: begin
  633.           if L.FAlias <> '' then
  634.             AL:= L.FAlias
  635.           else
  636.             AL:= 'Link'+IntToStr(X);
  637.           S:= AL+'.'+L.FLookupValue+' as '''+L.FName+'''';
  638.           T:= 'join '+L.FLookupTable+' '+AL+' on '+
  639.             AL+'.'+L.LookupField + ' = ';
  640.           if Pos('.', L.FFieldName) < 1 then
  641.             T:= T+FSourceLinks.FSourceAlias+'.';
  642.           T:= T+L.FFieldName;
  643.           J.Append(T);
  644.         end;
  645.       end;
  646.       if X > 0 then S:= ', '+S;
  647.       A(S);
  648.     end;
  649.     A('from '+FSourceLinks.FSourceTable+' '+FSourceLinks.FSourceAlias);
  650.     for X := 0 to FSourceLinks.FJoins.Count - 1 do
  651.       A(FSourceLinks.FJoins[X]);
  652.     for X := 0 to J.Count - 1 do
  653.       A(J[X]);
  654.     if FWhereSQL.Text <> '' then begin
  655.       A('where');
  656.       for X := 0 to FWhereSQL.Count - 1 do
  657.         A(FWhereSQL[X]);
  658.     end;
  659.   finally
  660.     J.Free;
  661.   end;
  662. end;
  663.  
  664. function TDataPump.GetWhereSQL: TStrings;
  665. begin
  666.   Result:= TStrings(FWhereSQL);
  667. end;
  668.  
  669. procedure TDataPump.LoadFromFile;
  670. var
  671.   I: TIniFile;
  672.   L: TStringList;
  673.   X: Integer;
  674.   S: String;
  675.   R: TDatabase;
  676. begin
  677.   FDatabases.Clear;
  678.   if FileExists(Filename) then begin
  679.     I:= TIniFile.Create(Filename);
  680.     try
  681.       L:= TStringList.Create;
  682.       try
  683.         I.ReadSections(L);
  684.         L.Sorted:= True;
  685.         L.Sort;
  686.         for X := 0 to L.Count - 1 do begin
  687.           S:= UpperCase(L[X]);
  688.           if Pos('CONN:', S) = 1 then begin
  689.             R:= FDatabases.Add;
  690.             R.Caption:= I.ReadString(S, 'Caption', '[NO NAME]');
  691.             R.ShortCaption:= I.ReadString(S, 'ShortCaption', '');
  692.             R.ConnectionString:=
  693.               I.ReadString(S, 'ConnectionString', '');
  694.             R.Schema:= I.ReadString(S, 'Schema', '');
  695.             R.Active:= I.ReadBool(S, 'Active', True);
  696.           end;
  697.         end;
  698.       finally
  699.         L.Free;
  700.       end;
  701.     finally
  702.       I.Free;
  703.     end;
  704.   end else begin
  705.     I:= TIniFile.Create(Filename);
  706.     try
  707.       I.WriteString('Settings', 'LastUsed', DateTimeToStr(Now));
  708.       I.UpdateFile;
  709.     finally
  710.       I.Free;
  711.     end;
  712.   end;
  713. end;
  714.  
  715. procedure TDataPump.SaveToFile;
  716. var
  717.   I: TIniFile;
  718.   X: Integer;
  719.   D: TDatabase;
  720.   L: TStringList;
  721. begin
  722.   ForceDirectories(ExtractFilePath(Filename));
  723.   if DirectoryExists(ExtractFilePath(Filename)) then begin
  724.     I:= TIniFile.Create(Filename);
  725.     try
  726.       L:= TStringList.Create;
  727.       try
  728.         I.ReadSections(L);
  729.         for X := 0 to L.Count - 1 do
  730.           I.EraseSection(L[X]);
  731.         for X := 0 to FDatabases.Count - 1 do begin
  732.           D:= FDatabases[X];
  733.           I.WriteString('Conn:'+IntToStr(X), 'Caption', D.Caption);
  734.           I.WriteString('Conn:'+IntToStr(X), 'ShortCaption', D.ShortCaption);
  735.           I.WriteString('Conn:'+IntToStr(X), 'ConnectionString', D.ConnectionString);
  736.           I.WriteString('Conn:'+IntToStr(X), 'Schema', D.Schema);
  737.           I.WriteBool('Conn:'+IntToStr(X), 'Active', D.Active);
  738.         end;
  739.       finally
  740.         L.Free;
  741.       end;
  742.     finally
  743.       I.Free;
  744.     end;
  745.   end else begin
  746.     raise Exception.Create('Could not create file "'+Filename+'"');
  747.   end;
  748. end;
  749.  
  750. function TDataPump.LookupID(ALink: TFieldLink; const Value: String): Integer;
  751. var
  752.   Q: TADOQuery;
  753.   S: String;
  754. begin
  755.   Result:= 0;
  756.   Q:= DestNewQuery;
  757.   try
  758.     S:= Trim(ALink.FSelectSQL);
  759.     if S = '' then begin
  760.  
  761.  
  762.     end;
  763.  
  764.  
  765.     Q.SQL.Text:= S;
  766.  
  767.   finally
  768.     Q.Free;
  769.   end;
  770. end;
  771.  
  772. function TDataPump.ImportField(ASource: TFieldLink; const Value: String): Integer;
  773. var
  774.   Dst: TFieldLink;
  775.   X: Integer;
  776.   SQL: String;
  777.   ID: Integer;
  778.   procedure A(const S: String);
  779.   begin
  780.     SQL:= SQL + S + sLineBreak;
  781.   end;
  782.   function ExecSQL(const S: String): Integer;
  783.   begin
  784.     FTempQry.SQL.Text:= S;
  785.     Result:= FTempQry.ExecSQL;
  786.   end;
  787. begin
  788.   Result:= 0;
  789.   FTempQry.Connection:= FDestDB;
  790.   for X := 0 to FDestLinks.Count - 1 do begin
  791.     if LowerCase(FDestLinks[X].FName) = LowerCase(ASource.FName) then begin
  792.       Dst:= FDestLinks[X];
  793.       case Dst.LinkType of
  794.         flText: begin
  795.           //Update with quotes
  796.           SQL:= Trim(Dst.FUpdateSQL);
  797.           if SQL = '' then begin
  798.             SQL:= 'update '+FSourceLinks.FSourceTable+' set '+Dst.FFieldName+' = '''+Value+''' where';
  799.           end;
  800.           ExecSQL(SQL);
  801.         end;
  802.         flInt, flFloat: begin
  803.           //Update without quotes
  804.           SQL:= Trim(Dst.FUpdateSQL);
  805.           if SQL = '' then begin
  806.             SQL:= 'update '+FSourceLinks.FSourceTable+' set '+Dst.FFieldName+' = '+Value+'';
  807.           end;
  808.           ExecSQL(SQL);
  809.         end;
  810.         flLookup: begin
  811.           //Update with quotes in linked lookup table
  812.           SQL:= ''; // Trim(Dst.FInsertSQL);
  813.           if SQL = '' then begin
  814.             A('select');
  815.             A(ASource.FLookupField+' as ID,');
  816.             A(ASource.FLookupValue+' as Value');
  817.             A('from '+ASource.FLookupTable);
  818.             A('where '+ASource.FLookupValue+' = '''+Value+'''');
  819.             FTempQry.Open;
  820.             if not FTempQry.IsEmpty then begin
  821.               FTempQry.First;
  822.               ID:= FTempQry.FieldByName('ID').AsInteger;
  823.             end else begin
  824.               //NOTE: How to handle if Identity is not enabled?
  825.               FTempQry.Append;
  826.               FTempQry.FieldByName(ASource.FLookupValue).AsString:= Value;
  827.               FTempQry.Post;
  828.               ID:= FTempQry.FieldByName(ASource.FLookupField).AsInteger;
  829.             end;
  830.             FTempQry.Close;
  831.             Result:= ID;
  832.           end else begin
  833.             SQL:= StringReplace(SQL, '<value>', Value, [rfReplaceAll,rfIgnoreCase]);
  834.             ExecSQL(SQL);
  835.           end;
  836.         end;
  837.       end;
  838.       Break;
  839.     end;
  840.   end;
  841. end;
  842.  
  843. //Replaces markup tags in a SQL statement with corresponding data
  844. function TDataPump.ReplaceSQL(AFieldLinks: TFieldLinks; ADataset: TInnoDataset;
  845.    const SQL: String): String;
  846. var
  847.   X: Integer;
  848.   L: TFieldLink;
  849. begin
  850.   Result:= SQL;
  851.   for X := 0 to AFieldLinks.Count - 1 do begin
  852.     L:= AFieldLinks[X];
  853.     Result:= StringReplace(Result, '<Source.'+L.Name+'>',
  854.       ADataset.FieldByName[L.FName].AsString,
  855.       [rfReplaceAll, rfIgnoreCase]);
  856.   end;
  857. end;
  858.  
  859. procedure TDataPump.PushData;
  860. var
  861.   Qry: TADOQuery;
  862.   Src: TInnoDataset;
  863.   X, Y: Integer; //Iterators
  864.   //S: String;
  865.   C: TInnoDatasetCol;
  866.   SL, DL: TFieldLink;
  867.   ID: Integer;
  868.   T: String; //Temp
  869.   SQL: String;
  870. begin
  871.   Src:= FSourceData;
  872.   Src.Clear;
  873.   Qry:= SourceNewQuery;
  874.   try
  875.     Qry.SQL.Text:= GetSourceSQL;
  876.     //Clipboard.AsText:= Qry.SQL.Text;
  877.     Qry.Open;
  878.     Src.LoadFromQuery(Qry);
  879.     Qry.Close;
  880.   finally
  881.     Qry.Free;
  882.   end;
  883.   Src.First;
  884.  
  885.   Qry:= DestNewQuery;
  886.   try
  887.     while not Src.EOF do begin
  888.       //Check for matching record, append if not
  889.       SQL:= FSourceLinks.Match.Text;
  890.       SQL:= ReplaceSQL(FSourceLinks, Src, SQL);
  891.       Qry.SQL.Text:= SQL;
  892.       Qry.Open;
  893.       if Qry.IsEmpty then begin
  894.         Qry.Append;
  895.         Qry[FSourceLinks.FSourceCaption]:= '';
  896.         Qry.Post;
  897.       end;
  898.       ID:= Qry.FieldByName('ID').AsInteger;
  899.       Qry.Close;
  900.       //Populate fields
  901.       for X := 0 to Src.FieldCount - 1 do begin
  902.         C:= Src.Cols[X];
  903.         SL:= FSourceLinks.FieldByName(C.FieldName);
  904.         if Assigned(SL) then begin
  905.           //ID:= ImportField(L, Src.FieldByIndex[X].AsString);
  906.         end;
  907.       end;
  908.       Src.Next;
  909.     end;
  910.   finally
  911.     Qry.Free;
  912.   end;
  913. end;
  914.  
  915. procedure TDataPump.SetActive(const Value: Boolean);
  916. begin
  917.   if Value then begin
  918.     if not FActive then begin
  919.       if (FSourceIndex >= 0) and (FDestIndex >= 0) and
  920.         (FSourceIndex < FDatabases.Count) and
  921.         (FDestIndex < FDatabases.Count) then
  922.       begin
  923.         FActive:= True;
  924.         try
  925.           FSourceLinks.LoadFromFile(SchemaDir+SourceConn.Schema);
  926.           FDestLinks.LoadFromFile(SchemaDir+DestConn.Schema);
  927.           FSourceDB.ConnectionString:= SourceConn.ConnectionString;
  928.           FDestDB.ConnectionString:= DestConn.ConnectionString;
  929.           FSourceDB.Connected:= True;
  930.           FDestDB.Connected:= True;
  931.         finally
  932.  
  933.         end;
  934.       end else begin
  935.         raise Exception.Create('Database Index out of bounds');
  936.       end;
  937.     end;
  938.   end else begin
  939.     if FActive then begin
  940.       try
  941.         FSourceDB.Connected:= False;
  942.         FDestDB.Connected:= False;
  943.       finally
  944.         FActive:= False;
  945.       end;
  946.     end;
  947.   end;
  948. end;
  949.  
  950. procedure TDataPump.DoOnConnect(const Connected: Boolean);
  951. begin
  952.   if assigned(FOnConnect) then
  953.     FOnConnect(Self, Connected);
  954. end;
  955.  
  956. procedure TDataPump.DBConnected(Sender: TObject);
  957. begin
  958.   if (FSourceDB.Connected) and (FDestDB.Connected) then
  959.     DoOnConnect(True);
  960. end;
  961.  
  962. procedure TDataPump.DBDisconnected(Sender: TObject);
  963. begin
  964.   if not (FSourceDB.Connected or FDestDB.Connected) then
  965.     DoOnConnect(False);
  966.   FSourceDB.Connected:= False;
  967.   FDestDB.Connected:= False;
  968. end;
  969.  
  970. function TDataPump.SourceNewQuery: TADOQuery;
  971. begin
  972.   Result:= TADOQuery.Create(nil);
  973.   Result.Connection:= FSourceDB;
  974. end;
  975.  
  976. function TDataPump.DestNewQuery: TADOQuery;
  977. begin
  978.   Result:= TADOQuery.Create(nil);
  979.   Result.Connection:= FDestDB;
  980. end;
  981.  
  982. function TDataPump.Filename: String;
  983. begin
  984.   Result:= ChangeFileExt(Application.ExeName, '.ini');
  985. end;
  986.  
  987. function TDataPump.SchemaDir: String;
  988. begin
  989.   Result:= IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName))+'Schemas\';
  990. end;
  991.  
  992. function TDataPump.SourceConn: TDatabase;
  993. begin
  994.   Result:= FDatabases[FSourceIndex];
  995. end;
  996.  
  997. function TDataPump.DestConn: TDatabase;
  998. begin
  999.   Result:= FDatabases[FDestIndex];
  1000. end;
  1001.  
  1002. function TDataPump.SourceDB: TADOConnection;
  1003. begin
  1004.   Result:= FSourceDB;
  1005. end;
  1006.  
  1007. function TDataPump.DestDB: TADOConnection;
  1008. begin
  1009.   Result:= FDestDB;
  1010. end;
  1011.  
  1012. procedure TDataPump.SetDestIndex(const Value: Integer);
  1013. begin
  1014.   FDestIndex := Value;
  1015. end;
  1016.  
  1017. procedure TDataPump.SetSourceIndex(const Value: Integer);
  1018. begin
  1019.   FSourceIndex := Value;
  1020. end;
  1021.  
  1022. procedure TDataPump.SetWhereSQL(const Value: TStrings);
  1023. begin
  1024.   FWhereSQL.Assign(Value);
  1025. end;
  1026.  
  1027. end.
Advertisement
Add Comment
Please, Sign In to add comment