123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- program createsql;
- {$mode objfpc}{$H+}
- uses
- {$IFDEF UNIX}{$IFDEF UseCThreads}
- cthreads,
- {$ENDIF}{$ENDIF}
- typinfo, Classes, SysUtils, CustApp, db, sqldb, fpdatadict,
- fpddfb,fpddpq,fpddOracle,fpddsqlite3,fpddmysql40,fpddmysql41,fpddmysql50, fpddodbc,
- strutils;
- type
- { TGenSQLApplication }
- TGenSQLApplication = class(TCustomApplication)
- private
- function CreateSQLEngine(AType: String): TFPDDSQLEngine;
- procedure ConnectToDatabase(const AType, ADatabaseName,AUserName,APassword: String);
- procedure DoConvertQuery(const S, T, KF: String; ST: TSTatementType);
- protected
- FConn : TSQLConnector;
- FDD : TFPDataDictionary;
- FENG : TFPDDSQLEngine;
- procedure DoRun; override;
- public
- constructor Create(TheOwner: TComponent); override;
- destructor Destroy; override;
- procedure WriteHelp(Const AMsg : string); virtual;
- end;
- { TGenSQLApplication }
- procedure TGenSQLApplication.ConnectToDatabase(Const AType,ADatabaseName,AUSerName,APassword : String);
- begin
- FConn:=TSQLConnector.Create(Self);
- FConn.ConnectorType:=AType;
- FConn.DatabaseName:=ADatabaseName;
- FConn.UserName:=AUserName;
- FConn.Password:=APassword;
- FConn.Transaction:=TSQLTransaction.Create(Self);
- FConn.Connected:=True;
- FDD:=TFPDataDictionary.Create;
- FENG:=CreateSQLEngine(AType);
- end;
- Function TGenSQLApplication.CreateSQLEngine(AType : String): TFPDDSQLEngine;
- begin
- Case lowercase(AType) of
- 'firebird' : Result:=TFPDDFBSQLEngine.Create;
- else
- Result:=TFPDDSQLEngine.Create;
- end;
- end;
- procedure TGenSQLApplication.DoConvertQuery(Const S,T,KF : String; ST : TSTatementType);
- Var
- Q : TSQLQuery;
- TD : TDDTableDef;
- Fields,KeyFields : TFPDDFieldList;
- I : Integer;
- F : TDDFieldDef;
- FN,SQL : String;
- begin
- TD:=FDD.Tables.AddTable(T);
- Q:=TSQLQuery.Create(Self);
- try
- Q.Database:=FConn;
- Q.Transaction:=FConn.Transaction;
- Q.SQL.Text:=S;
- Q.Open;
- TD.ImportFromDataset(Q);
- finally
- Q.Free;
- end;
- if (KF<>'') then
- begin
- KeyFields:=TFPDDFieldList.Create(False);
- For I:=1 to WordCount(KF,[',']) do
- begin
- FN:=ExtractWord(I,KF,[',']);
- F:=TD.Fields.FieldByName(FN);
- if (F=nil) then
- Writeln('Warning: Field ',FN,' does not exist.')
- else
- KeyFields.Add(F);
- end;
- end;
- Fields:=TFPDDFieldList.CreateFromTableDef(TD);
- try
- FEng.TableDef:=TD;
- Case ST of
- stDDL : SQL:=FEng.CreateCreateSQL(KeyFields);
- stSelect : SQL:=FEng.CreateSelectSQL(Fields,KeyFields);
- stInsert : SQL:=FEng.CreateInsertSQL(Fields);
- stUpdate : SQL:=FEng.CreateUpdateSQL(Fields,KeyFields);
- stDelete : SQL:=FEng.CreateDeleteSQL(KeyFields);
- end;
- Writeln(SQL);
- finally
- KeyFields.Free;
- end;
- end;
- procedure TGenSQLApplication.DoRun;
- var
- ErrorMsg: String;
- S,T,KF : String;
- I : Integer;
- ST : TStatementType;
- begin
- // quick check parameters
- ErrorMsg:=CheckOptions('hc:d:s:t:y:k:u:p:', 'help connection-type: database: sql: table: type: keyfields: user: password:');
- if ErrorMsg<>'' then
- WriteHelp(ErrorMsg);
- if HasOption('h', 'help') then
- WriteHelp('');
- S:=GetOptionValue('c','connection-type');
- T:=GetOptionValue('d','database');
- if (S='') or (t='') then
- Writehelp('Need database and connectiontype');
- ConnectToDatabase(S,T,GetOptionValue('u','user'),GetOptionValue('p','password'));
- S:=GetOptionValue('s','sql');
- T:=GetOptionValue('t','table');
- if (t='') then
- Writehelp('Need table name');
- i:=GetEnumValue(TypeInfo(TStatementType),'st'+GetOptionValue('y','type'));
- if I=-1 then
- Writehelp(Format('Unknown statement type : %s',[GetOptionValue('y','type')]));
- ST:=TStatementType(i);
- KF:=GetOptionValue('k','keyfields');
- if (KF='') and (st in [stselect, stupdate, stdelete]) then
- Writehelp('Need key fields for delete, select and update');
- if (S='') then
- S:='SELECT * FROM '+T+' WHERE 0=1';
- DoConvertQuery(S,T,KF,ST);
- // stop program loop
- Terminate;
- end;
- constructor TGenSQLApplication.Create(TheOwner: TComponent);
- begin
- inherited Create(TheOwner);
- StopOnException:=True;
- end;
- destructor TGenSQLApplication.Destroy;
- begin
- FreeAndNil(FConn);
- FreeAndNil(FDD);
- FreeAndNil(FENG);
- inherited Destroy;
- end;
- procedure TGenSQLApplication.WriteHelp(Const AMsg : string);
- Var
- S : String;
- L : TStrings;
- begin
- if AMsg<>'' then
- Writeln('Error : ',AMsg);
- Writeln('Usage: ', ExeName, ' [options]');
- Writeln('Where options is one or more of:');
- Writeln('-h --help this help message');
- Writeln('-c --connection-type=ctype Set connection type (required)' );
- Writeln('-d --database=db database connection name (required)');
- Writeln('-s --sql=sql SQL to execute (optional)');
- Writeln('-t --table=tablename tablename to use for statement (required)');
- Writeln('-y --type=stype Statement type (required) one of ddl, select, insert, update, delete)');
- Writeln('-k --keyfields=fields Comma-separated list of key fields (required for delete, update, optional for select,ddl)');
- Writeln('-u --user=username User name to connect to database');
- Writeln('-p --password=password Password of user to connect to database with');
- Writeln('Where ctype is one of : ');
- L:=TStringList.Create;
- try
- GetConnectionList(L);
- for S in L do
- Writeln(' ',lowercase(S));
- finally
- L.Free;
- end;
- Halt(Ord(AMsg<>''));
- end;
- var
- Application: TGenSQLApplication;
- begin
- Application:=TGenSQLApplication.Create(nil);
- Application.Title:='Generate SQL Demo';
- Application.Run;
- Application.Free;
- end.
|