How to set legacy_file_format in SQLite PDO? - sqlite

I need to make a new SQLite database with legacy_file_format on. I'm told you turn it on via a PRAGMA legacy_file_format = 1 to set the pragma on the database before you make it... but how can you do that before it's made? I'm using PHP PDO.

Pragmas like that need to be used between opening a brand new (file doesn't exist yet) database and the first table being created in it.
Note that the legacy_file_format pragma is becoming a no-op that has no effect in sqlite 3.31.

Related

SQLite Importer will overwrite my database when I load my application?

I have an Ionic App using SQLite. I don't have any problems with implementation.
The issue is that I need to import an SQL file using SQLitePorter to populate the database with configuration info.
But also, on the same database I have user info, so my question is:
Everytime I start the app, it will import the sql file, fill the database and probably overwrite my user data too? Since it is all on the same base?
I assume that you can always init your table using string queries inside your code. The problem is not that you are importing a .sql file. Right?
According to https://www.sqlitetutorial.net/sqlite-create-table/ it is obvious that you always create a table with [IF NOT EXISTS] switch. Writing a query like :
CREATE TABLE [IF NOT EXISTS] [schema_name].table_name (
column_1 data_type PRIMARY KEY);
you let sqlite to decide if it's going to create a table with the risk to overwrite an existing table. It is supposed that you can trust that sqlite is smart enough, not to overwrite any information especially if you use 'BEGIN TRANSACTION' - 'COMMIT' procedure.
I give my answer assuming that you have imported data and user data in distinct tables, so you can manipulate what you populate and what you don't. Is that right?
What I usually do, is to have a sql file like this:
DROP TABLE configutation_a;
DROP TABLE configutation_b;
CREATE TABLE configutation_a;
INSERT INTO configutation_a (...);
CREATE TABLE configutation_b;
INSERT INTO configutation_b (...);
CREATE TABLE IF NOT EXIST user_data (...);
This means that every time the app starts, I am updating with the configuration data I have at that time (that's is why we use http.get to get any configuration file from a remote repo in the future) and create user data only if user_data table is not there (hopefully initial start).
Conclusion: It's always a good practice, in my opinion, to trust a database product 100% and abstractly let it do any transaction that might give you some risk if you implemented your self in your code; since it gives a tool for that.For example, the keyword [if not exists], is always safer than implementing a table checker your self.
I hope that helps.
PS: In case you refer in create database procedure, SQLite, connects to a database file and it doesn't exist, it creates it. For someone comfortable in sqlite command line, when you type
sqlite3 /home/user/db/configuration.db will connect you with this db and if the file is not there, it will create it.

How to check database schema in swift?

I'm using SQLite.Swift and I'd like to know how to do to verify that the db still has the same schema when the application starts because on updtate, it's possible that the new application add columns in the table in which case I'm unable to use the existing db on the device.
I'll have to migrate/recreate the table.
How to do that please?
For tracking the database version, you can use the built in user-version variable that sqlite provides (sqlite does nothing with this variable, you are free to use it however you please). It starts at 0, and you can get/set this variable with the following sqlite statements:
> PRAGMA user_version;
> PRAGMA user_version = 1;
See this answer which discuss your requirement including making schema changes after update

SQLite dropped table not deleted

In the sqlite3 command line tool I dropped a table:
sqlite> DROP TABLE tableName;
It's a pretty big large table, so I would expect the sqlite file size to drop considerably. However, it hasn't changed at all.
What is the proper way to purge this table from the database completely?
The size of the file does not shrink when you delete a table in SQLite, you have to explicitely ask for it.
More info in the FAQ : http://www.sqlite.org/faq.html#q12
There are also some options to configure your database to have auto-vacuum enabled, you can find more info in the documentation of the VACUUM keyword here : http://www.sqlite.org/lang_vacuum.html and the PRAGMA option here : http://www.sqlite.org/pragma.html#pragma_auto_vacuum

Sqlite: How do I reset all database tables?

I want a debug function to do this, but I'm unaware of whether one already exists. Going through and using 'drop table' for each of my tables will be a pain.
Help appreciated.
Since the database is just one file, you can indeed just erase it. If you want something more automatic, you can use the following to do it all programmatically:
Recover your schema:
SELECT group_concat(sql,';') FROM sqlite_master;
Disconnect from the database
Delete the database file
Create your schema again with what was returned from the above query
If you used any particular options for your original database (page_size, etc), they will have to be declared manually as well.
to "drop database" for sqlite, simply delete the database file (and recreate if needed)

ADD COLUMN to sqlite db IF NOT EXISTS - flex/air sqlite?

I've got a flex/air app I've been working on, it uses a local sqlite database that is created on the initial application start.
I've added some features to the application and in the process I had to add a new field to one of the database tables. My questions is how to I go about getting the application to create one new field that is located in a table that already exists?
this is a the line that creates the table
stmt.text = "CREATE TABLE IF NOT EXISTS tbl_status ("+"status_id INTEGER PRIMARY KEY AUTOINCREMENT,"+" status_status TEXT)";
And now I'd like to add a status_default field.
thanks!
Thanks - MPelletier
I've add the code you provided and it does add the field, but now the next time I restart my app I get an error - 'status_default' already exists'.
So how can I go about adding some sort of a IF NOT EXISTS statement to the line you provided?
ALTER TABLE tbl_status ADD COLUMN status_default TEXT;
http://www.sqlite.org/lang_altertable.html
That being said, adding columns in SQLite is limited. You cannot add a column anywhere but after the last column in your table.
As for checking if the column already exists, PRAGMA table_info(tbl_status); will return a table listing the various columns of your table.
ADD ON:
I've been using a strategy in database design that allows me to distinguish which modifications are required. For this, you will need a new table (call it DBInfo), with one field (Integer, call it SchemaVersion). Alternately, there is also an internal value in SQLite called user_version, which can be set with a PRAGMA command. Your code can, on program startup, check for schema version number and apply changes accordingly, one version at a time.
Suppose a function named UpdateDBSchema(). This function will check for your database schema version, handle DBInfo not being there, and determine that the database is in version 0. The rest of this function could be just a large switch with different versions, nested in a loop (or other structure available to your platform of choice).
So for this first version, have an UpgradeDBVersion0To1() function, which will create this new table (DBInfo), add your status_default field, and set SchemaVersion to 1. In your code, add a constant that indicates the latest schema version, say LATEST_DB_VERSION, and set it to 1. In that way, your code and your database have a schema version, and you know you need to synch them if they are not equal.
When you need to make another change to your schema, set the LATEST_DB_VERSION constant to 2 and make a new UpgradeDBVersion1To2() function that will perform the required changes.
That way, your program can be ported easily, can connect to and upgrade an old database, etc.
I know this is an old question... however.
I've hit this precise problem in the SQLite implementation in Adobe AIR. I thought it would be possible to use the PRAGMA command to resolve, but since adobe air's implementation does not support the PRAGMA command, we need an alternative.
What I did, that I thought would be worth while sharing here, is this:
var sql:SQLStatement = new SQLStatement();
sql.sqlConnection = pp_db.dbConn;
sql.text = "SELECT NewField FROM TheTable";
sql.addEventListener(SQLEvent.RESULT, function(evt:SQLEvent):void {
});
sql.addEventListener(SQLErrorEvent.ERROR, function(err:SQLErrorEvent):void {
var sql:SQLStatement = new SQLStatement();
sql.sqlConnection = pp_db.dbConn;
sql.text = "ALTER TABLE TheTable ADD COLUMN NewField NUMERIC;";
sql.execute();
sql.addEventListener(SQLEvent.RESULT, function (evt:SQLEvent):void {
});
});
sql.execute();
Hope it helps someone.
I solved a similar problem using the answer from this question:
ALTER TABLE ADD COLUMN IF NOT EXISTS in SQLite
Use built in user_version parameter to keep track of your updates. You set it using:
PRAGMA user_version = 1
and you retrieve it using
PRAGMA user_version
So basically retrieve user_version (it's 0 by default), check if it's 0. If yes, perform your updates and set it to 1. If you have more updates in the future, check if it's 1, perform updates and set it to 0. And so on...
In some cases I execute the command and get the exception for "duplicate column". Just a quick solution, not the perfect.

Resources