Recent

Author Topic: Converting a Project from TDbf to SQLite [SOLVED]  (Read 9764 times)

1HuntnMan

  • Sr. Member
  • ****
  • Posts: 349
  • From Delphi 7 to Lazarus
    • NewFound Photo Art
Re: Converting a Project from TDbf to SQLite
« Reply #90 on: March 26, 2025, 05:01:02 pm »
Not going to switch to FireBird/SQL, sticking with SQLite3 because even though a lot of tables, not that much data. This project is for photographers.
For example, how do you SELECT from let's say, 4 tables, i.e the Contacts mgt. part of the Project?
Most all examples I see are SELECT from one table. So, is this correct?
Code: Pascal  [Select][+][-]
  1. procedure TFrmCntksMgt.FormShow(Sender: TObject);
  2. begin
  3.   //-> Set the SQL select statement for the CONTACTS table...
  4.   DmPMSDataBase.QueryPMSDB.SQL.Text:= 'SELECT * FROM CONTACTS';
  5.   //-> Set the SQL select statement for the CLIENTS table...
  6.   DmPMSDataBase.QueryPMSDB.SQL.Text:= 'SELECT * FROM CLIENTS';
  7.   //-> Set the SQL select statement for the STATES/PROVINCES table...
  8.   DmPMSDataBase.QueryPMSDB.SQL.Text:= 'SELECT * FROM STPROVCODES';
  9.   //-> Set the SQL select statement for the COUNTRIES table...
  10.   DmPMSDataBase.QueryPMSDB.SQL.Text:= 'SELECT * FROM COUNTRIES';
  11.   //-> Now use the standard TDataset methods...
  12.   DmPMSDataBase.QueryPMSDB.Open;
  13.  DSStates.DataSet.FieldByName('STPROVCODE').DisplayWidth:= 2;
  14.   DSStates.DataSet.FieldByName('STPROVNAME').DisplayWidth:= 12;
  15. //----------------------------
  16.   DSCountries.DataSet.FieldByName('CODE').DisplayWidth:= 2;
  17.   DSCountries.DataSet.FieldByName('COUNTRY').DisplayWidth:= 10;
  18.   DSClients.DataSet.FieldByName('CUSTOMER').DisplayWidth:= 12;
  19.   {...Fix this later for counting total Contacts  records with a SELECT COUNT or the like}
  20.   EditTTLContacts.ReadOnly:= False;
  21.   IntRecCount:= DSContacts.ExactRecordCount;
  22.   EditTTLContacts.Text:= IntToStr(IntRecCount);
  23.   EditTTLContacts.ReadOnly:= True;}
  24.   JvDBSrchByIndex.Text:= '';
  25.   BitBtnSaveCntk.Enabled:= False;
  26.   BitBtnCancelCntk.Enabled:= False;
  27.   Screen.Cursor:= crDefault;
  28.   DBGridCntks.SetFocus;
  29. end;
  30.  
This form has a DBNav, etc. on the top panel, below that is a DBGrid for panning thru the records and below the DBGrid are TDBEdits and LookupCombo's for data entry.

TRon

  • Hero Member
  • *****
  • Posts: 4321
Re: Converting a Project from TDbf to SQLite
« Reply #91 on: March 26, 2025, 10:06:56 pm »
Most all examples I see are SELECT from one table. So, is this correct?
Well, there is good news and there is bad news.

The good news is that the select statements (with the exception of ending them with a semicolon) seems about right.

The bad news is, and I generalize here (which is technically wrong), there can be only one select statement per query (and be active at a point in time)

In case a query is only used to be active for a certain view/form and it is the only query active then such a query can be re-used by closing the query, changing the select statement and opening the query again so that it can be reused for another view/form.

In case that is not possible, for example the countries-view form also contains a button that allows to view the customers in a view/form, then you can not use that same query but need to create another one.

PS: in case it make it perhaps easier to understand as you seem to be familiar with it: a query /IS/ a dataset.
« Last Edit: March 26, 2025, 10:28:07 pm by TRon »
Today is tomorrow's yesterday.

egsuh

  • Hero Member
  • *****
  • Posts: 1594
Re: Converting a Project from TDbf to SQLite
« Reply #92 on: March 27, 2025, 03:51:07 am »
No..


Code: Pascal  [Select][+][-]
  1. procedure TFrmCntksMgt.FormShow(Sender: TObject);
  2. begin
  3.      QueryContacts.SQL.Text:= 'SELECT * FROM CONTACTS';
  4.      QueryClients.SQL.Text:= 'SELECT * FROM CLIENTS';
  5.      QueryStprovcodes.SQL.Text:= 'SELECT * FROM STPROVCODES';
  6.      QueryCouuntries.SQL.Text:= 'SELECT * FROM COUNTRIES';
  7.  
  8.      QueryContacts.open;
  9.      QueryClients.OPpen;
  10.      QueryStprovcodes.Open;
  11.      QueryCouuntries.Open;
  12.  
  13.     // I think you'd better do followings with DBGrid
  14.     //  DSStates.DataSet.FieldByName('STPROVCODE').DisplayWidth:= 2;  
  15.     //  DSStates.DataSet.FieldByName('STPROVNAME').DisplayWidth:= 12;
  16.  
  17.        DGStates.Columns[3].DisplayFormat :=...;   // DGStates is DBGrid, and TDBGrid.columns are 0-based indexes.
  18.        DGStates.Columns[3].Width :=...;
  19.        DGStates.Columns[4].DisplayFormat :=...;
  20.        DGStates.Columns[4].Width :=...;
  21.  
  22.     //---------------------------- the same as above as well.
  23.  
  24.        DGCountries.Columns[0].width := 50;
  25.        // .........
  26.       // DSCountries.DataSet.FieldByName('CODE').DisplayWidth:= 2;
  27.      //  DSCountries.DataSet.FieldByName('COUNTRY').DisplayWidth:= 10;
  28.       // DSClients.DataSet.FieldByName('CUSTOMER').DisplayWidth:= 12;
  29.  
  30.   {...Fix this later for counting total Contacts  records with a SELECT COUNT or the like}
  31.  
  32.   // should look like:
  33.  
  34.     with queryTemp do begin
  35.            SQL.Text = 'select count (*) from contacts where client_id=:cid';
  36.            Params[0].AsInteger := QueryClients.fieldByName('Client_id').AsInteger;
  37.            Open;
  38.            tcount := Fields[0].AsInteger;   // tcount is an integer variable.
  39.           Close;
  40.    end;
  41.  
  42.    // And tcount is the total number of contacts for the selected client.
  43.  
  44.  
  45.     EditTTLContacts.ReadOnly:= False;
  46.     IntRecCount:= DSContacts.ExactRecordCount;
  47.     EditTTLContacts.Text:= IntToStr(IntRecCount);
  48.     EditTTLContacts.ReadOnly:= True;}
  49.     JvDBSrchByIndex.Text:= '';
  50.     BitBtnSaveCntk.Enabled:= False;
  51.     BitBtnCancelCntk.Enabled:= False;
  52.     Screen.Cursor:= crDefault;
  53.     DBGridCntks.SetFocus;
  54. end;

Focus on datasets, like TSQLQuery, TSQLite3DataSet, etc., not DBGrid or Datasource.

You do this:

1. Drop TSQLite3Connection component and TSQLTransaction component on a datamodule, DmPMSDataBase in your case.
   - Set database of TSQLite3Connection to your DB file,
   - set transaction to the transaction component.

     try to "connect" by clicking the checkbox in the object inspector. Should be stay in "checked" state.

2. Create a form, add dmPMSDataBase in the "uses" clause of the form. Then,
    - drop TSQLQuery, Tdatasource, TDBGrid, and TDBEdit, TDBLabel, TDBMemo as you need.
    - Set TSQLquery.Database to dmPMSDataBase.SQLite3Connection.
    - Set TDataSource.DataSet to the SQLQuery.
    - Set the datasource of all the data controls (DBGrid, DBEdit, DBMemo, DBLabels, etc.) to the datasource on the form.
    - Type in SQL property of TSQLQuery as "Select * from Clients"

    - Try to Open it clicking "Active" at the object inspector.

     If everything is OK, you should be able to see the contents of the table at the design time -- without running the application.

3. Create second form, and to the same things as step 2, using different tables. You can add more forms.

   Every form will have the same names by default, SQLQuery1, DataSource1, DBGrid1, etc. , unless you rename them. Doesn't matter.

4. Once you have made a few forms, then Set all the "active" components to inactive state. SQLite3Connection, and TSQLQueries of every form.  And write some codes:

      at   DataModuleCreate
            SQLite3Connection.Connected := true;  
      at Forms' FormShow events:
            SQLQuery1.Active := True;

That's all.  Be careful that datamodule is created first.

And run the application. Then if everything is OK, you must be able to see the contents of the first form.

You can add a main form, add some menus, and when click a menu, each form will be shown.

Then add more forms as necessary.


This is the most basic approach.

1HuntnMan

  • Sr. Member
  • ****
  • Posts: 349
  • From Delphi 7 to Lazarus
    • NewFound Photo Art
Re: Converting a Project from TDbf to SQLite
« Reply #93 on: March 28, 2025, 08:40:19 pm »
Okay, this is awesome. But this example is from the Contacts Mgt. form, called from the main form. The way I designed this the main form is for accessing Clients Mgt., Contacts Mgt., Appointments, Sales Orders, Invoices, etc. These forms have a main table as does this one Contacts Mgt., the Contacts table. The Clients table, States/Provinces table and the Countries tables are just lookups for the Contact via TJvDBLookupCombo's, i.e. selecting the Client, select the state and the country is all.
So, for every table, I select the table all records, the open each one. I open it per EGSuh. Also, thanks EGSuh for the counting the contact records code. I use this on the main forms just for info.
Also, the DSSTates.Columns displayformats is just for the JvDBLookupCombo. TRon helped me with that long time ago. The main DBGrid at the top is just for the user to pan thru the existing records, no data editing/inserting. They can use the roller top of their moused to roll up and down if hovering above the DBGrid.

I need to get the TSQLite3DataSet installed.  Attempted to Package-Install/Uninstall packages but it disappeared in the process. It didn't appear in the SQLdb components. I'm going to uninstall Laz and reinstall it and try again.
Tks, 1HuntnMan

paweld

  • Hero Member
  • *****
  • Posts: 1360
Re: Converting a Project from TDbf to SQLite
« Reply #94 on: March 28, 2025, 08:56:56 pm »
Quote from: 1HuntnMan
It didn't appear in the SQLdb components.
because it appears on the “Data Access” tab

P.S. if you don't know which tab the component is on use the component finder (find component.png)
« Last Edit: March 28, 2025, 09:01:53 pm by paweld »
Best regards / Pozdrawiam
paweld

egsuh

  • Hero Member
  • *****
  • Posts: 1594
Re: Converting a Project from TDbf to SQLite
« Reply #95 on: March 29, 2025, 04:11:36 am »
Quote
Clients Mgt., Contacts Mgt., Appointments, Sales Orders, Invoices,

If you want to like them in a way that when a clinet is selected, only appointments, sales orders, invoices, etc. of that specific client are shown, you can define Afterscroll event.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.qryClientsAfterScroll(DataSet: TDataSet);
  2. begin
  3.     with qryAppointments do begin
  4.         Close;
  5.         SQL.Text := 'select * from qryAppointments where clientid=:cid';
  6.         params[0].AsInteger := Dataset.FieldByName('ClientID').AsInteger;
  7.         Open;
  8.     end;
  9. end;
  10.  
         

Then whenever you select a client, then only those records of appointments with that client will be show. When the databases get larger, this is better approach, ad SQLite3DataSet will make a copy of the whole table first.

1HuntnMan

  • Sr. Member
  • ****
  • Posts: 349
  • From Delphi 7 to Lazarus
    • NewFound Photo Art
Re: Converting a Project from TDbf to SQLite
« Reply #96 on: March 30, 2025, 06:40:51 pm »
PAWeld et. al.,
Do you recommend using the SQLite3DataSet? I'm currently using just 4 components: TSQLite3Connection, TSQLTransaction, TSQLQuery and TDataSource as far as converting to SQLite3. TRon recommended and advised that I can add/install the TSQLite3DataSet from Package->Install/Uninstall Packages->Available for Installation, the sqlite3laz 0.4 or sqlitelaz0.4 package. About a week ago, I tried that but couldn't find it. PAWELD said the component should be located in the Data Access tab after the install but I didn't see it. Maybe I didn't do something correctly so uninstalled Laz and reinstalled it.
Now under Available for Installation, I see 2 sqlite3 components to install:  sqlite3laz 0.4 and sqlitelaz 0.4. I assume the SQLite3DataSet is included in the sqlite3laz 0.4, correct????

1HuntnMan

  • Sr. Member
  • ****
  • Posts: 349
  • From Delphi 7 to Lazarus
    • NewFound Photo Art
Re: Converting a Project from TDbf to SQLite
« Reply #97 on: March 30, 2025, 06:53:10 pm »
Okay, found it... sqlite3laz 0.4, trying to install again...

1HuntnMan

  • Sr. Member
  • ****
  • Posts: 349
  • From Delphi 7 to Lazarus
    • NewFound Photo Art
Re: Converting a Project from TDbf to SQLite
« Reply #98 on: March 30, 2025, 06:59:52 pm »
Or should I install the  C:\lazarus\components\sqlite\sqlite3laz.lpk

TRon

  • Hero Member
  • *****
  • Posts: 4321
Re: Converting a Project from TDbf to SQLite
« Reply #99 on: March 30, 2025, 08:45:32 pm »
Menu->package->install/uninstal packages
Available for installation:
type sql
select sqlite3laz 0.4
press install selection
press save and rebuild IDE

Follow paweld's instructions to locate the component

Quote
Do you recommend using the SQLite3DataSet
Personally, no (but note that is a pure personal opinion).

As stated before: a query /is/ a dataset, the only difference is that the query itself determines what becomes part of the dataset, e.g. provides much more flexibility on what data is present in the dataset. That is why I prefer it over a 'normal' dataset.

You opinion might differ because you are converting existing code-base.
Today is tomorrow's yesterday.

1HuntnMan

  • Sr. Member
  • ****
  • Posts: 349
  • From Delphi 7 to Lazarus
    • NewFound Photo Art
Re: Converting a Project from TDbf to SQLite
« Reply #100 on: March 30, 2025, 09:31:10 pm »
Thanks TRon and all...

paweld

  • Hero Member
  • *****
  • Posts: 1360
Re: Converting a Project from TDbf to SQLite
« Reply #101 on: March 31, 2025, 05:33:39 am »
PAWeld et. al.,
Do you recommend using the SQLite3DataSet?
No
Quote
I'm currently using just 4 components: TSQLite3Connection, TSQLTransaction, TSQLQuery and TDataSource as far as converting to SQLite3.
And that's what I would stay with. From what I remember it's SQLite3DataSet for each occurrence opens a new connection.
In my opinion, you should stay with what you described, just make sure that the connection to the database is only one for the entire application (TSQLite3Connection).
Best regards / Pozdrawiam
paweld

1HuntnMan

  • Sr. Member
  • ****
  • Posts: 349
  • From Delphi 7 to Lazarus
    • NewFound Photo Art
Re: Converting a Project from TDbf to SQLite
« Reply #102 on: April 01, 2025, 07:30:37 pm »
Okay All, as far as my maintenance forms, i.e. CountriesMaint, StatesProvMaint, PayStatus, etc. These forms work fine because easy to setup because they require only 1 table each from the DataBase, PMSDB.sqlite3. EGSUH explained how to open 4 tables from the DataBase but I'm not getting it. My DataModule has only 3 components on it: ConnectPMSDB, TransPMSDB and QueryPMSDB. Now, back to the DataModule. I can have both the ConnectPMSDB component and the TransPMSDB component on the DataModule.  But for multiple tables to be queried, SELECT * FROM Contacts, Clients, States & Countries I need to put a separate Query component on the Contacts Mgt. form, one for each DataSource correct? in order to query 4 different tables from the database on one form, i.e. Contacts Mgt.
I can't do this below, correct?:
Code: Pascal  [Select][+][-]
  1.   DmPMSDataBase.QueryPMSDB.SQL.Text:= 'SELECT * FROM CONTACTS';
  2.   DmPMSDataBase.QueryPMSDB.SQL.Text:= 'SELECT * FROM CLIENTS';
  3.   DmPMSDataBase.QueryPMSDB.SQL.Text:= 'SELECT * FROM STPROVCODES';
  4.   DmPMSDataBase.QueryPMSDB.SQL.Text:= 'SELECT * FROM COUNTRIES';
  5.  
I'm going to have to have a different TSQLQuery component on the Contacts Mgt. form, not the one on the DataModule, for each Query Correct for all 4 tables to have an active query at the same time.

Also, I finally got the TSQLiteDataSet installed, I had to put the SQLite3.dll into the Lazarus directory. But don't see how to use it, there's no description for any of Properties. I'll have to research to find an example. But if you can help out with just my Contacts Mgt. form, the others I can figure out. See the form attached...

1HuntnMan

  • Sr. Member
  • ****
  • Posts: 349
  • From Delphi 7 to Lazarus
    • NewFound Photo Art
Re: Converting a Project from TDbf to SQLite
« Reply #103 on: April 01, 2025, 08:27:44 pm »
SQLite3DataSet! Maybe that's the way because I can point it to each DataSource. Pull in the FieldDefs needed, the FileName?, Primary Key for the table and assign the SQL statement. Hmmmm

TRon

  • Hero Member
  • *****
  • Posts: 4321
Re: Converting a Project from TDbf to SQLite
« Reply #104 on: April 02, 2025, 08:34:04 am »
...
My DataModule has only 3 components on it: ConnectPMSDB, TransPMSDB and QueryPMSDB. Now, back to the DataModule. I can have both the ConnectPMSDB component and the TransPMSDB component on the DataModule.  But for multiple tables to be queried, SELECT * FROM Contacts, Clients, States & Countries I need to put a separate Query component on the Contacts Mgt. form, one for each DataSource correct?
No but with the caveat that it depends. Since not all information required to answer correctly is available I have to take a guess here but in normal situations this requires 2 queries in a s named master-detail setup (see also wiki).

Quote
I can't do this below, correct?:
That is correct: you can not do that. Or to be more precise, you can do that but it will not result in something that you looking for. In SQL-speak it is nonsense.

Quote
I'm going to have to have a different TSQLQuery component on the Contacts Mgt. form, not the one on the DataModule, for each Query Correct for all 4 tables to have an active query at the same time.
That is where the guessing part comes into play because of lacking information. Looking at the form picture that was posted it seems like a classic master-detail relationship. One query to 'browse' the contacts and depending on which contact is 'active' show the details for that contact.

In the detail query you make a selct statement that 'collect's all the relevant data (read: fields from different tables) for the selected customer based on the ID of the customer.

What exactly that query looks like depends on what indices are present and how the indices of the tables are linked between each other.
Today is tomorrow's yesterday.

 

TinyPortal © 2005-2018