Topic: Copy DB table to Update DB file

Hi Dmitry and All,


The following utility app has been posted sometime ago by Kim if I remember correctly.  Only some visuals are changed as I could understand it's workings.
https://s17.postimg.org/xo143rnbj/z_Temp100.png


I couldn't get it working, unless I'm doing something wrong.
Purpose is to update earlier version DB file created  with newer version which would have DB tables structure changes such as new DB table/s, Field/s etc.
For instance, I created a MVD application called XYZ v1. Used it and added data to it over time. Then I updated XYZ v1 to XYZ v2. In the process I have added some new tables , new fields to existing DB tables, renamed some existing DB tables and fields. In this situation  XYZ v1 DB file doesn't work with  XYZ v2


It'd be nice to have some little utility that updates older DB file to newer one without loss of existing data. Doing it through SQL Studio is a cumbersome job especially if new tables contains many fields and application was used by many different individual users.


This utility aims to copy DB tables of DB file one at a time. It'd be even better old db gets updated with new one with just a click after specifying old and new DB file locations. It can be used not only by MVD developers but end users too.


Dmitry, Could you possibly give or sell us such an extremely useful utility please?

Post's attachments

Attachment icon CopyDBTable.zip 6.3 kb, 508 downloads since 2018-01-07 

Adam
God... please help me become the person my dog thinks I am.

Re: Copy DB table to Update DB file

Hello AD1408 and happy new year,


I known the problem ! My application has had so many changes, that it can be hard to tracks user version and adapt their database to the new format (because they don't want to start from scratch and loose their data).


To compare two sqlite databases, I use this tool : Sqlite Compare
https://www.codeproject.com/Articles/22 … re-Utility


This nice (and Free) utility will compare for you two sqlite databases (structure only, or structure and data) and generates SQL scripts to upgrade from old model to new model.


Tables, triggers, foreign keys.... it handles everything and quite well.


Each time I release a new version, the conversion scripts comes with it. When the new application starts (with the old data), version numbers are compared and the scripts are applied on a copy of the user database.


The only thing the user has to do is replace the current database with the converted one.


Hope this helps


Cheers


Mathias

I'm a very good housekeeper !
Each time I get a divorce, I keep the house

Zaza Gabor

Re: Copy DB table to Update DB file

Hi Mathias,


Happy New Year to you too...............


Thank you very much for the link and info...............


Script created by SQLite Compare utility, seems to be not compatible with MVD.
How can I convert the following SQLite Compare script to MVD script?

BEGIN TRANSACTION;
-- Creating table Application from scratch (simple ALTER TABLE is not enough)

CREATE TABLE temp_Application_534011718
(
    id INTEGER PRIMARY KEY ASC AUTOINCREMENT,
    appName TEXT NOT NULL,
    code TEXT,
    issues TEXT,
    todo TEXT,
    notes TEXT,
    id_Status INTEGER,
    id_Groups INTEGER,
    id_Categories INTEGER,
    FOREIGN KEY (id_Status) REFERENCES Status(id),
    FOREIGN KEY (id_Groups) REFERENCES Groups(id),
    FOREIGN KEY (id_Categories) REFERENCES Categories(id)
);

-- Copying rows from original table to the new table

INSERT INTO temp_Application_534011718 (id,appName,code,issues,todo,notes,id_Status,id_Groups,id_Categories) SELECT id,appName,code,issues,todo,notes,id_Status,id_Groups,id_Categories FROM Application;

-- Droping the original table and renaming the temporary table

DROP TABLE Application;
ALTER TABLE temp_Application_534011718 RENAME TO Application;

DROP TABLE Issues;

COMMIT TRANSACTION;
Adam
God... please help me become the person my dog thinks I am.

Re: Copy DB table to Update DB file

Adam,
If you are placing the SQL script inside an MVD project script, then you need to place the SQL scripts inside MVD SQLExecute commands.
SqlExecute('Create....');
SqlExecute('Insert.....');
SqlExecute('Drop......');
SqlExecute('Alter......');

Re: Copy DB table to Update DB file

Hi EHW,


Thank you very much...........


Unfortunately, I couldn't do it.


Please see the attached sample project.

Post's attachments

Attachment icon DBFile Update v2.zip 45.31 kb, 481 downloads since 2018-01-09 

Adam
God... please help me become the person my dog thinks I am.

Re: Copy DB table to Update DB file

Adam,
Your project is fixed. However, you can only run it one time. If you try running it a second time, you will get duplicate component errors. So you need to comment out the SqlExecute lines between Begin and End after running it the first time. I think Mathias had some sort of versioning process and he could put those SqlExecute lines inside an If statement so it would only execute those lines if there was a different version.


You may want to consider creating a separate project just to upgrade the database in question. You can place the SqlExecute statements within the Begin and End of the upgrade project.That's what I do when there is an upgrade to the database. You will need to change the settings.ini file in the upgrade folder. There needs to be a "server=" line after the DBMS=SQLite entry to point to the database to be upgraded.

Post's attachments

Attachment icon DBFile Update v2 Fixed.zip 624.12 kb, 523 downloads since 2018-01-09 

7 (edited by mathmathou 2018-01-09 06:35:51)

Re: Copy DB table to Update DB file

Hello both of you old friends smile


AD, what you want to do is use an SQLTransaction. With this, you can chain all your SQLExecute commands and execute them all at once.


No need for

BEGIN TRANSACTION;

at the beginning and no need for

COMMIT TRANSACTION;

at the end, this is all contained in the MVD SQLTransaction.


On  a button click, this would give you something like that (with the example you posted previoulsy)

procedure Form1_Button1_OnClick (Sender: string; var Cancel: boolean);
var
    //Declare a SQLTransaction variable
    SqliteTr: TDBXSqliteTransaction;
begin
    //Initiate the transaction
    SqliteTr := BeginSQLiteTransaction;

    //SQL command 1
    SQLExecute('CREATE TABLE temp_Application_534011718'+
    '('+
    'id INTEGER PRIMARY KEY ASC AUTOINCREMENT,'+
    'appName TEXT NOT NULL,'+
    'code TEXT,'+
    'issues TEXT,'+
    'todo TEXT,'+
    'notes TEXT,'+
    'id_Status INTEGER,'+
    'id_Groups INTEGER,'+
    'id_Categories INTEGER,'+
    'FOREIGN KEY (id_Status) REFERENCES Status(id),'+
    'FOREIGN KEY (id_Groups) REFERENCES Groups(id),'+
    'FOREIGN KEY (id_Categories) REFERENCES Categories(id)'+
    ');');

    //SQL command 2
    SQLExecute('INSERT INTO temp_Application_534011718 (id,appName,code,issues,todo,notes,id_Status,id_Groups,id_Categories) SELECT id,appName,code,issues,todo,notes,id_Status,id_Groups,id_Categories FROM Application;');

    //SQL command 3
    SQLExecute('DROP TABLE Application;');

    //SQL command 4
    SQLExecute('ALTER TABLE temp_Application_534011718 RENAME TO Application;');

    //SQL command 5
    SQLExecute('DROP TABLE Issues;');

    //Commit the SQLTransaction
    CommitSQLiteTransaction(SqliteTr);
end;

end;

Hope this helped


Cheers


Mathias

I'm a very good housekeeper !
Each time I get a divorce, I keep the house

Zaza Gabor

Re: Copy DB table to Update DB file

Hi Mathias,


I hope life is treating you well and you are enjoying it.


Thank you very much for your kind help...................
Truly appreciated.........................


I have tried to apply it a smaller test project but couldn't get it right properly. It returns an error....

 { SQLite Compare script::::
BEGIN TRANSACTION;
-- Adding missing table columns

ALTER TABLE company ADD COLUMN coPhone TEXT;

CREATE TABLE products
(
    id INTEGER PRIMARY KEY ASC AUTOINCREMENT,
    pName TEXT,
    pPrice REAL,
    id_company INTEGER,
    FOREIGN KEY (id_company) REFERENCES company(id) ON DELETE CASCADE
);
COMMIT TRANSACTION;
   }

//////////////////////////////////////////////////////////////////////////

procedure Form1_Button8_OnClick (Sender: TObject; var Cancel: boolean);
var SqliteTr: TDBXSqliteTransaction;
begin
//Initiate the transaction
SqliteTr := BeginSQLiteTransaction;

SQLExecute('ALTER TABLE company ADD COLUMN coPhone TEXT;');

SQLExecute('CREATE TABLE products'+
    '('+
'id INTEGER PRIMARY KEY ASC AUTOINCREMENT,'+
'pName TEXT,'+
'pPrice REAL,'+
'id_company INTEGER REFERENCES company(id) ON DELETE CASCADE,'+
')');

//Commit the SQLTransaction
CommitSQLiteTransaction(SqliteTr);
end;
Adam
God... please help me become the person my dog thinks I am.

Re: Copy DB table to Update DB file

Hello  AD,


I had a quick look at your code, and I think there is a extra comma at the end of your script


Find this :

'id_company INTEGER REFERENCES company(id) ON DELETE CASCADE,'+
')');

Try to replace with :

'id_company INTEGER REFERENCES company(id) ON DELETE CASCADE')');

Let me known if this solved the error.


Take care my friend. Cheers


Mathias

I'm a very good housekeeper !
Each time I get a divorce, I keep the house

Zaza Gabor

Re: Copy DB table to Update DB file

Hi Mathias,


Indeed, it did.
Thank you so much for the quick help .......................


If I understood this correctly, after we run the  db update script on new app, we'd take out update db button, compile and send it to end user with a blank sqlite.db file. All end user needs to do is overwrite blank db file with the one he has containing his data. Am I correct?

Adam
God... please help me become the person my dog thinks I am.

Re: Copy DB table to Update DB file

Hello AD,


Right now, I'm uploading the tool I made for you to look at it.

I'm a very good housekeeper !
Each time I get a divorce, I keep the house

Zaza Gabor

Re: Copy DB table to Update DB file

Basically, this is a second program.


The user :
- starts the program
- loads his "old database"
- no mater where the database was, it is copied in the  DB_OLD subdirectory of the tool
- the version of the database is checked
- if version is OK, conversion process can begin
- at the end, the newly created database is saved in DB_NEW subdirectory

All that is left for the user is the replace the database shipped with the new version of the application with this newly converted one, and start the program.


Code is commented


Hope this helps


Cheers


Mathias

I'm a very good housekeeper !
Each time I get a divorce, I keep the house

Zaza Gabor

Re: Copy DB table to Update DB file

Sounds great Math !!!


Looks like, attachment missed or failed to upload.
Looking forward for it...

Adam
God... please help me become the person my dog thinks I am.

Re: Copy DB table to Update DB file

Sent you a forum email with the download link smile

I'm a very good housekeeper !
Each time I get a divorce, I keep the house

Zaza Gabor

Re: Copy DB table to Update DB file

Hi Mathias,


Sorry, it's my bad. I didn't think of checking email. Now I got it.


Looks great and comprehensive.......................
Very kind of you................
Thank you very much.................................................................
Truly appreciated ...............................................................................


I'll be looking and exploring it with a great joy...

Adam
God... please help me become the person my dog thinks I am.

Re: Copy DB table to Update DB file

MVD's way of handling SQL usually gives me some issues that I cannot resolve myself. There are so many punctuations used and it's rules. On the other hand SQLite Compare uses much more easy to read and understand SQLite. I assume that's the difference of C# handling and Pascal/Delphi.


I was trying to translate SQLite Compare script to MVD. I've already spend almost 5 hours and still couldn't resolve it. I got about 4 errors atm:
https://s17.postimg.org/47nudhqmn/z_Temp101.png


Here is the script that producing errors:

procedure Form1_Button7_OnClick (Sender: TObject; var Cancel: boolean);
var SqliteTr: TDBXSqliteTransaction;
begin
    //Initiate the transaction
    SqliteTr := BeginSQLiteTransaction;

    //SQL command 1
    SQLExecute('CREATE TABLE temp_Application_534011718'+
    '('+
    'id INTEGER PRIMARY KEY ASC AUTOINCREMENT,'+
    'appName TEXT NOT NULL,'+
    'code TEXT,'+
    'issues TEXT,'+
    'todo TEXT,'+
    'notes TEXT,'+
    'id_Status INTEGER,'+
    'id_Groups INTEGER,'+
    'id_Categories INTEGER,'+
    'FOREIGN KEY (id_Status) REFERENCES Status(id),'+
    'FOREIGN KEY (id_Groups) REFERENCES Groups(id),'+
    'FOREIGN KEY (id_Categories) REFERENCES Categories(id)'+
    ')');

    //SQL command 2 (line break used after id_Categories) ' +'
    SQLExecute('INSERT INTO temp_Application_534011718 (id,appName,code,issues,todo,notes,id_Status,id_Groups,id_Categories)'
              +'SELECT id,appName,code,issues,todo,notes,id_Status,id_Groups,id_Categories FROM Application;');

    //SQL command 3
    SQLExecute('DROP TABLE Application;');

    //SQL command 4
    SQLExecute('ALTER TABLE temp_Application_534011718 RENAME TO Application;');

    //SQL command 5////
    SQLExecute('CREATE TABLE issueFilter;'+
    '('+
    'id INTEGER PRIMARY KEY ASC AUTOINCREMENT,'+
    'issueFilter TEXT,'
    ')');

    //SQL command 6
    SQLExecute('CREATE TABLE temp_Issues_1655911537'+
    '('+
    'id INTEGER PRIMARY KEY ASC AUTOINCREMENT,'+
    'issueDate TEXT,'+
    'issueName TEXT NOT NULL,'+
    'issueReoprted TEXT,'+
    'issueDesc TEXT,'+
    'id_Application INTEGER,'+
    'id_issueFilter INTEGER,'+
    'issueFilterValue TEXT,'+
    'FOREIGN KEY (id_Application) REFERENCES Application(id) ON DELETE CASCADE,'+
    'FOREIGN KEY (id_issueFilter) REFERENCES issueFilter(id'+
    ')');

    //SQL command 7
    SQLExecute('INSERT INTO temp_Issues_1655911537 (id,issueDate,issueName,issueReoprted,issueDesc,id_Application,id_issueFilter,issueFilterValue)'
              +'SELECT id,issueDate,issueName,issueReoprted,issueDesc,id_Application,NULL AS id_issueFilter,NULL AS issueFilterValue FROM Issues;');

    //SQL command 8
    SQLExecute('DROP TABLE Issues;');

    //SQL command 9
    SQLExecute('ALTER TABLE temp_Issues_1655911537 RENAME TO Issues;');

    //Commit the SQLTransaction
    CommitSQLiteTransaction(SqliteTr);
end;
Adam
God... please help me become the person my dog thinks I am.

Re: Copy DB table to Update DB file

Hello AD,


QUERY 5, there are two typos :
Replace

SQLExecute('CREATE TABLE issueFilter;'+

With

SQLExecute('CREATE TABLE issueFilter'+

There is a nasty "  ;  " in your code where it should not be
Replace

'issueFilter TEXT,'

With

'issueFilter TEXT'

No "  ,  " at the end because this is the last line of instruction


QUERY6 found just one
Replace at the end

')');

With

'))');

I think you closed one less "  (  " than you had opened


Other errors are due to the missing tables that could not be created.


Let me known if this solved your issue


Cheers



Mathias

I'm a very good housekeeper !
Each time I get a divorce, I keep the house

Zaza Gabor

18 (edited by mathmathou 2018-01-10 20:44:08)

Re: Copy DB table to Update DB file

Better safe than sorry,


QUERY 7
Add a blank space at the end of the first line, your commands are not separated.
Replace

issueFilterValue)'

With

issueFilterValue) '

Other than that I don't see anything else


Cheers



Math

I'm a very good housekeeper !
Each time I get a divorce, I keep the house

Zaza Gabor

Re: Copy DB table to Update DB file

Hi Mathias,


Thank you very much for your patience and extremely kind help.......................................................


Still couldn't get it working fully. Script syntax errors are corrected. However I get error on running the script. Most likely I'm doing things wrong.
1. I rename old db (with data) to sqliteData
2. On SQLite Compare utility, I put the old db that's renamed to sqliteData to left and new db (blank) sqlite to right.
3. Generate script left --> to right.


https://s17.postimg.org/ya2j6irxb/z_Temp103b.png
Is "Comparison error" something to be concerned about?


Here is the script generated by SQLite Compare:

BEGIN TRANSACTION;

CREATE TABLE issueFilter
(
    id INTEGER PRIMARY KEY ASC AUTOINCREMENT,
    issueFilter TEXT
);

-- Creating table Issues from scratch (simple ALTER TABLE is not enough)

CREATE TABLE temp_Issues_1848543519
(
    id INTEGER PRIMARY KEY ASC AUTOINCREMENT,
    issueDate TEXT,
    issueName TEXT NOT NULL,
    issueReoprted TEXT,
    issueDesc TEXT,
    id_Application INTEGER,
    id_issueFilter INTEGER,
    issueFilterValue TEXT,
    FOREIGN KEY (id_Application) REFERENCES Application(id) ON DELETE CASCADE,
    FOREIGN KEY (id_issueFilter) REFERENCES issueFilter(id)
);

-- Copying rows from original table to the new table

INSERT INTO temp_Issues_1848543519 (id,issueDate,issueName,issueReoprted,issueDesc,id_Application,id_issueFilter,issueFilterValue) SELECT id,issueDate,issueName,issueReoprted,issueDesc,id_Application,id_issueFilter,issueFilterValue FROM Issues;

-- Droping the original table and renaming the temporary table

DROP TABLE Issues;
ALTER TABLE temp_Issues_1848543519 RENAME TO Issues;

COMMIT TRANSACTION;

And here is the MVD version of the above script:

procedure Form1_Button7_OnClick (Sender: TObject; var Cancel: boolean);
var SqliteTr: TDBXSqliteTransaction;
begin
    //Initiate the transaction
    SqliteTr := BeginSQLiteTransaction;

    //SQL command 1
    SQLExecute('CREATE TABLE issueFilter'+
    '('+
    'issueFilter TEXT'+
    ')');

    //SQL command 2
    SQLExecute('CREATE TABLE temp_Issues_1848543519'+
    '('+
    'id INTEGER PRIMARY KEY ASC AUTOINCREMENT,'+
    'issueDate TEXT,'+
    'issueName TEXT NOT NULL,'+
    'issueReoprted TEXT,'+
    'issueDesc TEXT,'+
    'id_Application INTEGER,'+
    'id_issueFilter INTEGER,'+
    'issueFilterValue TEXT,'+
    'FOREIGN KEY (id_Application) REFERENCES Application(id) ON DELETE CASCADE,'+
    'FOREIGN KEY (id_issueFilter) REFERENCES issueFilter(id'+
    '))');

    //SQL command 3
    SQLExecute('INSERT INTO temp_Issues_1848543519 (id,issueDate,issueName,issueReoprted,issueDesc,id_Application,id_issueFilter,issueFilterValue) '
              +'SELECT id,issueDate,issueName,issueReoprted,issueDesc,id_Application,id_issueFilter,issueFilterValue FROM Issues;');

    //SQL command 4
    SQLExecute('DROP TABLE Issues;');

    //SQL command 5
    SQLExecute('ALTER TABLE temp_Issues_1848543519 RENAME TO Issues;');

    //Commit the SQLTransaction
    CommitSQLiteTransaction(SqliteTr);
end;

When I run it and click on db update button (Button7) I get the following error:
https://s17.postimg.org/g79gey13z/z_Temp102.png


I comment out :

SQLExecute('CREATE TABLE issueFilter'+
    '('+
    'issueFilter TEXT'+
    ')');

Then script runs without error. After, I rename sqliteData.db to sqlite.db and copy over blank (new app db). This time I get error saying there is no such table  issueFilter....

Adam
God... please help me become the person my dog thinks I am.

20 (edited by mathmathou 2018-01-17 06:08:40)

Re: Copy DB table to Update DB file

Hello AD,


Took me some time, but I think I have something for you.


Try this little tool and tell me what you think. Instructions are included inside, just click on the 'question mark' icon, but here they are as well :

  • use SQliteCompare to generate a conversion script

  • start the tool and select your database to convert

  • load the conversion script

  • wait

https://mega.nz/#!tkoklabQ!Sbm6R5jMuVhh … d7GLpadsJU


If this tool works, I could build a version you could distribute with the needed script and instructions to your users, as well as upload it here for all users if you think it is useful.


I had to use Delphi with RAD Studio because I could not find a way to disable Foreign Key Constraints on an attached database with MVD (they are enabled again at the end of the conversion process).
The idea was to build a generic tool, not one with hard-coded instructions that would only work for a specific version and a specific database scheme. This is why the conversion script has to be loaded. But then, if the only thing you have to provide to your users is the conversion script along with the new version of your application, that is simple enough for them to do.


Cheers


Mathias

PS : many things could go wrong, starting with the SQLite connection. Let me known

I'm a very good housekeeper !
Each time I get a divorce, I keep the house

Zaza Gabor

Re: Copy DB table to Update DB file

Hi Mathias,


Wooow....... However much I thank you for the excellent job yo have done here is not enough.........................
I tested it with one DB and it worked like a charm.


Using this wonderful utility is not a problem for us.
I was wondering is it possible to improve end user experience further by reducing down to use of your utility SCT only...


I'm thinking that it may be done in ways perhaps:
1. SCT compares  DBs and converts without the need to use additional application. I understand, this wouldn't be an easy option.
2. SCT uses SQLite Compare utility in the background. SCT gets SQLite Compare to do the comparing and generating the script and using generated script to convert as it does currently somehow. In this case we'd include SQLite Compare within SCT package and pass to end user. End user would only need to run SCT to convert their old DB.


Once again, thank you very much for the great work you have done.............................

Adam
God... please help me become the person my dog thinks I am.

Re: Copy DB table to Update DB file

where can i find conversion script?

Re: Copy DB table to Update DB file

jonibek wrote:

where can i find conversion script?


If you mean SQLiteCompare utility that generates the script, link is on Math's excellent utility SCT - bottom of the form - Assumung you have downloaded from his post above.
For your convenience here is the same link:
https://www.codeproject.com/Articles/22 … re-Utility

Adam
God... please help me become the person my dog thinks I am.

Re: Copy DB table to Update DB file

thanks

Re: Copy DB table to Update DB file

mathmathou wrote:

Hello AD,


Took me some time, but I think I have something for you.


Try this little tool and tell me what you think. Instructions are included inside, just click on the 'question mark' icon, but here they are as well :

  • use SQliteCompare to generate a conversion script

  • start the tool and select your database to convert

  • load the conversion script

  • wait

https://mega.nz/#!tkoklabQ!Sbm6R5jMuVhh … d7GLpadsJU


If this tool works, I could build a version you could distribute with the needed script and instructions to your users, as well as upload it here for all users if you think it is useful.


I had to use Delphi with RAD Studio because I could not find a way to disable Foreign Key Constraints on an attached database with MVD (they are enabled again at the end of the conversion process).
The idea was to build a generic tool, not one with hard-coded instructions that would only work for a specific version and a specific database scheme. This is why the conversion script has to be loaded. But then, if the only thing you have to provide to your users is the conversion script along with the new version of your application, that is simple enough for them to do.


Cheers


Mathias

PS : many things could go wrong, starting with the SQLite connection. Let me known


Mathias,

Would you be willing to share it with me?  The file is gone.

Sonny.