mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-10-31 06:02:02 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			270 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			270 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
| unit mainform;
 | |
| 
 | |
| {$mode objfpc}{$H+}
 | |
| 
 | |
| interface
 | |
| 
 | |
| uses
 | |
|   Classes, SysUtils, FileUtil, Forms, Controls, Dialogs, StdCtrls,
 | |
|   dbconfiggui, dbconfig,
 | |
|   {General db unit}sqldb,
 | |
|   {For EDataBaseError}db,
 | |
|   {Now we add all databases we want to support, otherwise their drivers won't be loaded}
 | |
|   {$IFNDEF Solaris}IBConnection,{$ENDIF}pqconnection,sqlite3conn,
 | |
|   mssqlconn,mysql50conn,mysql51conn,mysql55conn,odbcconn,oracleconnection,
 | |
|   sqlscript {the unit that contains tsqlscript};
 | |
| 
 | |
| type
 | |
| 
 | |
|   { TForm1 }
 | |
| 
 | |
|   TForm1 = class(TForm)
 | |
|     CmdCopyDDL: TButton;
 | |
|     CmdOpenSQL: TButton;
 | |
|     CmdCopyDML: TButton;
 | |
|     CmdRunScript: TButton;
 | |
|     OpenDialog1: TOpenDialog;
 | |
|     ScriptMemo: TMemo;
 | |
|     procedure CmdCopyDDLClick(Sender: TObject);
 | |
|     procedure CmdCopyDMLClick(Sender: TObject);
 | |
|     procedure CmdOpenSQLClick(Sender: TObject);
 | |
|     procedure CmdRunScriptClick(Sender: TObject);
 | |
|     procedure FormCreate(Sender: TObject);
 | |
|     procedure FormDestroy(Sender: TObject);
 | |
|   private
 | |
|     FConn: TSQLConnector;
 | |
|     FQuery: TSQLQuery;
 | |
|     FTran: TSQLTransaction;
 | |
|     // Run database connection test when asked
 | |
|     function ConnectionTest(ChosenConfig: TDBConnectionConfig): boolean;
 | |
|     // Display script error to the user
 | |
|     procedure ShowScriptException(Sender: TObject; Statement: TStrings; TheException: Exception; var Continue: boolean);
 | |
|   public
 | |
| 
 | |
|   end;
 | |
| 
 | |
| var
 | |
|   Form1: TForm1;
 | |
| 
 | |
| implementation
 | |
| 
 | |
| {$R *.lfm}
 | |
| 
 | |
| { TForm1 }
 | |
| 
 | |
| procedure TForm1.FormCreate(Sender: TObject);
 | |
| var
 | |
|   LoginForm: TDBConfigForm;
 | |
| begin
 | |
|   FConn:=TSQLConnector.Create(nil);
 | |
|   FQuery:=TSQLQuery.Create(nil);
 | |
|   FTran:=TSQLTransaction.Create(nil);
 | |
|   FConn.Transaction:=FTran;
 | |
|   FQuery.DataBase:=FConn;
 | |
| 
 | |
|   LoginForm:=TDBConfigForm.Create(self);
 | |
|   try
 | |
|     // The test button on dbconfiggui will link to this procedure:
 | |
|     LoginForm.ConnectionTestCallback:=@ConnectionTest;
 | |
|     LoginForm.ConnectorType.Clear; //remove any default connectors
 | |
|     // Now add the dbs that you support - use the name of the *ConnectionDef.TypeName property
 | |
|     {$IFNDEF Solaris}
 | |
|     // Not available on Solaris
 | |
|     LoginForm.ConnectorType.AddItem('Firebird', nil);
 | |
|     {$ENDIF}
 | |
|     LoginForm.ConnectorType.AddItem('MSSQLServer', nil);
 | |
|     LoginForm.ConnectorType.AddItem('MySQL50', nil);
 | |
|     LoginForm.ConnectorType.AddItem('MySQL51', nil);
 | |
|     LoginForm.ConnectorType.AddItem('MySQL55', nil);
 | |
|     LoginForm.ConnectorType.AddItem('ODBC', nil);
 | |
|     LoginForm.ConnectorType.AddItem('Oracle', nil);
 | |
|     LoginForm.ConnectorType.AddItem('PostGreSQL', nil);
 | |
|     LoginForm.ConnectorType.AddItem('SQLite3', nil);
 | |
|     LoginForm.ConnectorType.AddItem('Sybase', nil);
 | |
|     case LoginForm.ShowModal of
 | |
|     mrOK:
 | |
|       begin
 | |
|         // User wants to connect, so copy over db info
 | |
|         FConn.ConnectorType:=LoginForm.Config.DBType;
 | |
|         FConn.HostName:=LoginForm.Config.DBHost;
 | |
|         FConn.DatabaseName:=LoginForm.Config.DBPath;
 | |
|         FConn.UserName:=LoginForm.Config.DBUser;
 | |
|         FConn.Password:=LoginForm.Config.DBPassword;
 | |
|         FConn.Transaction:=FTran;
 | |
|       end;
 | |
|     mrCancel:
 | |
|       begin
 | |
|         ShowMessage('You canceled the database login. Application will terminate.');
 | |
|         Application.Terminate;
 | |
|       end;
 | |
|     end;
 | |
|   finally
 | |
|     LoginForm.Free;
 | |
|   end;
 | |
|   // Get a script before the user's eyes:
 | |
|   CmdCopyDDLClick(nil);
 | |
| end;
 | |
| 
 | |
| procedure TForm1.CmdCopyDDLClick(Sender: TObject);
 | |
| // Script that sets up tables as used in SQLdb_Tutorial1..3
 | |
| // Also includes a photo blob used in the LazReport tutorial
 | |
| // Notice we include 2 SQL statements, each terminated with ;
 | |
| const ScriptText=
 | |
|   'CREATE TABLE CUSTOMER '+LineEnding+
 | |
|   '( '+LineEnding+
 | |
|   '  CUST_NO INTEGER NOT NULL, '+LineEnding+
 | |
|   '  CUSTOMER VARCHAR(25) NOT NULL, '+LineEnding+
 | |
|   '  CITY VARCHAR(25), '+LineEnding+
 | |
|   '  COUNTRY VARCHAR(15), '+LineEnding+
 | |
|   '  CONSTRAINT CT_CUSTOMER_PK PRIMARY KEY (CUST_NO) '+LineEnding+
 | |
|   '); '+LineEnding+
 | |
|   'CREATE TABLE EMPLOYEE '+LineEnding+
 | |
|   '( '+LineEnding+
 | |
|   '  EMP_NO INTEGER NOT NULL, '+LineEnding+
 | |
|   '  FIRST_NAME VARCHAR(15) NOT NULL, '+LineEnding+
 | |
|   '  LAST_NAME VARCHAR(20) NOT NULL, '+LineEnding+
 | |
|   '  PHONE_EXT VARCHAR(4), '+LineEnding+
 | |
|   '  JOB_CODE VARCHAR(5) NOT NULL, '+LineEnding+
 | |
|   '  JOB_GRADE INTEGER NOT NULL, '+LineEnding+
 | |
|   '  JOB_COUNTRY VARCHAR(15) NOT NULL, '+LineEnding+
 | |
|   '  SALARY NUMERIC(10,2) NOT NULL, '+LineEnding+
 | |
|   '  PHOTO BLOB SUB_TYPE BINARY, '+LineEnding+
 | |
|   '  CONSTRAINT CT_EMPLOYEE_PK PRIMARY KEY (EMP_NO) '+LineEnding+
 | |
|   ');';
 | |
| begin
 | |
|   Scriptmemo.Lines.Text:=ScriptText;
 | |
| end;
 | |
| 
 | |
| procedure TForm1.CmdCopyDMLClick(Sender: TObject);
 | |
| // Script that fills the table with sample data as used in SQLdb_Tutorial1..3
 | |
| // The double quotes inside the statements will be parsed by the Pascal compiler and
 | |
| // end up as single quotes in the actual ScriptText string, like SQL expects it.
 | |
| const ScriptText=
 | |
|   'INSERT INTO CUSTOMER (CUST_NO, CUSTOMER, CITY, COUNTRY) VALUES (1, ''Michael Design'', ''San Diego'', ''USA''); '+LineEnding+
 | |
|   'INSERT INTO CUSTOMER (CUST_NO, CUSTOMER, CITY, COUNTRY) VALUES (2, ''VC Technologies'', ''Dallas'', ''USA''); '+LineEnding+
 | |
|   'INSERT INTO CUSTOMER (CUST_NO, CUSTOMER, CITY, COUNTRY) VALUES (3, ''Klämpfl, Van Canneyt'', ''Boston'', ''USA''); '+LineEnding+
 | |
|   'INSERT INTO CUSTOMER (CUST_NO, CUSTOMER, CITY, COUNTRY) VALUES (4, ''Felipe Bank'', ''Manchester'', ''England''); '+LineEnding+
 | |
|   'INSERT INTO CUSTOMER (CUST_NO, CUSTOMER, CITY, COUNTRY) VALUES (5, ''Joost Systems, LTD.'', ''Central Hong Kong'', ''Hong Kong''); '+LineEnding+
 | |
|   'INSERT INTO CUSTOMER (CUST_NO, CUSTOMER, CITY, COUNTRY) VALUES (6, ''Van der Voort Int.'', ''Ottawa'', ''Canada''); '+LineEnding+
 | |
|   'INSERT INTO CUSTOMER (CUST_NO, CUSTOMER, CITY, COUNTRY) VALUES (7, ''Mrs. Mauvais'', ''Pebble Beach'', ''USA''); '+LineEnding+
 | |
|   'INSERT INTO CUSTOMER (CUST_NO, CUSTOMER, CITY, COUNTRY) VALUES (8, ''Asinine Vacation Rentals'', ''Lihue'', ''USA''); '+LineEnding+
 | |
|   'INSERT INTO CUSTOMER (CUST_NO, CUSTOMER, CITY, COUNTRY) VALUES (9, ''Fax'', ''Turtle Island'', ''Fiji''); '+LineEnding+
 | |
|   'INSERT INTO CUSTOMER (CUST_NO, CUSTOMER, CITY, COUNTRY) VALUES (10, ''FPC Corporation'', ''Tokyo'', ''Japan''); '+LineEnding+
 | |
|   'INSERT INTO CUSTOMER (CUST_NO, CUSTOMER, CITY, COUNTRY) VALUES (11, ''Dynamic Intelligence Corp'', ''Zurich'', ''Switzerland''); '+LineEnding+
 | |
|   'INSERT INTO CUSTOMER (CUST_NO, CUSTOMER, CITY, COUNTRY) VALUES (12, ''3D-Pad Corp.'', ''Paris'', ''France''); '+LineEnding+
 | |
|   'INSERT INTO CUSTOMER (CUST_NO, CUSTOMER, CITY, COUNTRY) VALUES (13, ''Swen Export, Ltd.'', ''Milan'', ''Italy''); '+LineEnding+
 | |
|   'INSERT INTO CUSTOMER (CUST_NO, CUSTOMER, CITY, COUNTRY) VALUES (14, ''Graeme Consulting'', ''Brussels'', ''Belgium''); '+LineEnding+
 | |
|   'INSERT INTO CUSTOMER (CUST_NO, CUSTOMER, CITY, COUNTRY) VALUES (15, ''Klenin Inc.'', ''Den Haag'', ''Netherlands''); '+LineEnding+
 | |
|   'INSERT INTO employee(emp_no, first_name, last_name, phone_ext, job_code, job_grade,  '+LineEnding+
 | |
|   '  job_country, salary) '+LineEnding+
 | |
|   '  VALUES (1,''William'',''Shatner'',''1702'',''CEO'',1,''USA'',48000); '+LineEnding+
 | |
|   'INSERT INTO employee(emp_no, first_name, last_name, phone_ext, job_code, job_grade,  '+LineEnding+
 | |
|   '  job_country, salary) '+LineEnding+
 | |
|   '  VALUES (2,''Ivan'',''Rzeszow'',''9802'',''Eng'',2,''Russia'',38000); '+LineEnding+
 | |
|   'INSERT INTO employee(emp_no, first_name, last_name, phone_ext, job_code, job_grade,  '+LineEnding+
 | |
|   '  job_country, salary) '+LineEnding+
 | |
|   '  VALUES (3,''Erin'',''Powell'',''1703'',''Admin'',2,''USA'',45368); ';
 | |
| begin
 | |
|   Scriptmemo.Lines.Text:=ScriptText;
 | |
| end;
 | |
| 
 | |
| procedure TForm1.CmdOpenSQLClick(Sender: TObject);
 | |
| begin
 | |
|   if OpenDialog1.Execute then
 | |
|   begin
 | |
|     ScriptMemo.Clear;
 | |
|     ScriptMemo.Lines.LoadFromFile(OpenDialog1.FileName);
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| procedure TForm1.CmdRunScriptClick(Sender: TObject);
 | |
| // The heart of the program: runs the script in the memo
 | |
| var
 | |
|   OurScript: TSQLScript;
 | |
| begin
 | |
|   OurScript:=TSQLScript.Create(nil);
 | |
|   try
 | |
|     OurScript.Database:=FConn; //Indicate what db & ...
 | |
|     OurScript.Transaction:=FTran; // ... transaction we actually want to run the script against
 | |
|     OurScript.Script.Assign(ScriptMemo.Lines); //Copy over the script itself
 | |
|     //Now set some options:
 | |
|     OurScript.UseCommit:=true; //try process any COMMITs inside the script, instead of batching everything together. See readme.txt though
 | |
|     //SET TERM is Firebird specific, used when creating stored procedures etc.
 | |
|     if FConn.ConnectorType='Firebird' then
 | |
|       OurScript.UseSetTerm:=true
 | |
|     else
 | |
|       OurScript.UseSetTerm:=false;
 | |
|     OurScript.CommentsInSQL:=false; //Send commits to db server as well; could be useful to troubleshoot by monitoring all SQL statements at the server
 | |
|     OurScript.OnException:=@ShowScriptException; //when errors occur, let this procedure handle the error display
 | |
|     try
 | |
|       if not(FTran.Active) then
 | |
|         FTran.StartTransaction; //better safe than sorry
 | |
|       OurScript.Execute;
 | |
|       FTran.Commit; //Make sure entire script is committed to the db
 | |
|       ShowMessage('Script was successfully run.');
 | |
|     except
 | |
|       on E: EDataBaseError do
 | |
|       begin
 | |
|         // Error was already displayed via ShowScriptException, so no need for this:
 | |
|         //ShowMessage('Error running script: '+E.Message);
 | |
|         FTran.Rollback;
 | |
|       end;
 | |
|     end;
 | |
|   finally
 | |
|     OurScript.Free;
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| procedure TForm1.FormDestroy(Sender: TObject);
 | |
| begin
 | |
|   FQuery.Free;
 | |
|   FTran.Free;
 | |
|   FConn.Free;
 | |
| end;
 | |
| 
 | |
| function TForm1.ConnectionTest(ChosenConfig: TDBConnectionConfig): boolean;
 | |
| // Callback function that uses the info in dbconfiggui to test a connection
 | |
| // and return the result of the test to dbconfiggui
 | |
| var
 | |
|   // Generic database connector...
 | |
|   Conn: TSQLConnector;
 | |
| begin
 | |
|   result:=false;
 | |
|   Conn:=TSQLConnector.Create(nil);
 | |
|   Screen.Cursor:=crHourglass;
 | |
|   try
 | |
|     // ...actual connector type is determined by this property.
 | |
|     // Make sure the ChosenConfig.DBType string matches
 | |
|     // the connectortype (e.g. see the string in the
 | |
|     // T*ConnectionDef.TypeName for that connector .
 | |
|     Conn.ConnectorType:=ChosenConfig.DBType;
 | |
|     Conn.HostName:=ChosenConfig.DBHost;
 | |
|     Conn.DatabaseName:=ChosenConfig.DBPath;
 | |
|     Conn.UserName:=ChosenConfig.DBUser;
 | |
|     Conn.Password:=ChosenConfig.DBPassword;
 | |
|     try
 | |
|       Conn.Open;
 | |
|       result:=Conn.Connected;
 | |
|     except
 | |
|       // Result is already false
 | |
|     end;
 | |
|     Conn.Close;
 | |
|   finally
 | |
|     Screen.Cursor:=crDefault;
 | |
|     Conn.Free;
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| procedure TForm1.ShowScriptException(Sender: TObject; Statement: TStrings;
 | |
|   TheException: Exception; var Continue: boolean);
 | |
| begin
 | |
|   // Shows script execution error to user
 | |
|   // todo: should really be a separate form with a memo big enough to display a large statement
 | |
|   ShowMessage('Script error: '+TheException.Message+LineEnding+
 | |
|     Statement.Text);
 | |
|   Continue:=false; //indicate script should stop
 | |
| end;
 | |
| 
 | |
| end.
 | |
| 
 | 
