Mobile applications / Database support on mobile devices |
On the device, Genero Mobile uses the SQLite database only.
When running an app in development mode (where the app runs on a computer), you can use any database server that Genero supports for the operating system of the server-side app.
When running the application on the device, only SQLite can be used. The database must be created at the first application execution, or it must be delivered as the default database in the .ipa or .apk package.
SQLite stores data in UTF-8 codeset, mobile apps will by default run in UTF-8 and with character length semantics (FGL_LENGTH_SEMANTICS=CHAR).
Mobile applications usually create their database at first execution. The SQLite database file must be created in the application sandbox, in a writable directory. If the database file does not exist in the current working directory (os.Path.pwd()), create an empty file and then perform a CONNECT TO instruction.
For more details, see Creating a database from programs.
SQLite database file format is cross-platform. Instead of creating the database the first time the application starts, you might want to prepare a default database file in your development environment, and include it in the .ipa / .apk package.
SQLite does not have strict data type checking as traditional databases. If you define a table column as a DECIMAL, you can still store character values in that column. Pay attention to this SQLite specific feature, to avoid invalid storage and type conversion errors in your application.
Consider using the following data types for maximum portability, especially when data needs to be synchronized with a central database server, where the data types must match to the types used in the mobile application: CHAR, VARCHAR, DATE, DATETIME YEAR TO MINUTE, DATETIME YEAR TO FRACTION(3), DECIMAL, SMALLINT, INTEGER, BIGINT, BYTE, TEXT.
SQLite can be slow at doing commits, due to the data integrity technique used for transactions. Since each INSERT / UPDATE / DELETE statements acts as an individual transaction (i.e., auto-commit), there will be as many transactions/commits as data manipulation statements. For example, it takes about 10 seconds to insert 1000 rows on an Intel core i7 2.60GHz CPU / 5400.0 RPM HDD computer.
BEGIN WORK FOR i=1 TO mylog.getLength() -- INSERT / UPDATE / DELETE statements END FOR COMMIT WORK
SQLite 3.6.19 and + support foreign key constraints, with ON DELETE CASCADE and ON UPDATE CASCADE options. By default, however, foreign key constraints are not enforced. Each application must explicitly turn on the feature with a PRAGMA command. Immediately after the database connection, you can perform the PRAGMA command in an EXECUTE IMMEDIATE statement:
CONNECT TO connstr AS "c1" EXECUTE IMMEDIATE "PRAGMA foreign_keys = ON"
By default, when deleting rows, SQLite keeps the unused database file pages for future storage. As result, when deleting a large amount of data, the database file might be larger than necessary. Consider truncating the database file with the VACUUM SQL command (in an EXECUTE IMMEDIATE statement), if disk space is limited and when a lot of database rows were deleted.
Depending on the application, the VACUUM command can be executed:
CONNECT TO connstr AS "c1" EXECUTE IMMEDIATE "VACUUM"
Two different Android apps (each packaged as a separate .apk) execute in their own sandbox, but have access to the storage area (SD-CARD) and therefore could share a common database file.
SQLite handles concurrent access to the same database file by setting a lock on the entire db file when modifying data (INSERT/UPDATE/DELETE). By default, if a writer process locks the file, other processes must wait until the lock owner process completes its transaction and releases the lock.
Because of Informix compatibility, Genero BDL uses a default lock timeout or zero (i.e., not waiting for locks to be released). As result, when writing to a database file that is locked by another process, if the isolation level is SERIALIZATION (the default with SQLite), an application will get the SQL error -244.
CONNECT TO connstr AS "c1" SET LOCK MODE TO 5 -- seconds
The second process will then wait until the first process releases the lock. If transactions are short (milliseconds), having processes waiting for each other is transparent to the user.