I am creating an Ionic5 app(with Vue3) using capacitor-sqlite plugin. I am also trying to use TypeORM on top all this.
I can connect to the sqlite database using capacitor but for some reason the migrations does not seem to be getting registered at all and always comes out as an empty array with the following code:
// App.vue
import {createConnection} from "typeorm";
import {CapacitorSQLite, SQLiteConnection} from "@capacitor-community/sqlite";
onBeforeMount(async () => {
const sqlite = new SQLiteConnection(CapacitorSQLite);
createConnection({
type: 'capacitor',
driver: sqlite,
database: 'mydrivetime',
synchronize: false,
migrationsRun: false,
logging: true,
entities: [
"User"
],
migrations: [
"1626771964722-UserCreate"
],
}).then(async connection => {
console.log('migrations', connection.migrations);
console.log('isConnected', connection.isConnected);
connection.runMigrations()
.then(() => {
console.log("migrations successful");
}).catch(error => console.log(JSON.stringify(error)));
});
});
I get the following output for this even though I have the migration setup on the same path:
⚡️ [log] - migrations []
⚡️ [log] - isConnected true
⚡️ [log] - migrations successful
This is the migration file which I have in the same path as App.vue
. I also tried putting it in a separate folder and trying to glob it but no luck.
import {MigrationInterface, QueryRunner} from "typeorm";
export class UserCreate1626771964722 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
CREATE TABLE "user" (
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
"firstName" varchar NOT NULL,
"age" integer NOT NULL
)
`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
DROP TABLE "user"
`);
}
}
I don't have any other settings anywhere else and I am not sure why the migration (or entity) are not getting registered. Here is the full console.log
of the connection
object:
{
"migrations": [],
"subscribers": [],
"entityMetadatas": [],
"name": "default",
"options": {
"type": "capacitor",
"driver": {
"sqlite": {},
"_connectionDict": {}
},
"database": "mydrivetime",
"synchronize": false,
"migrationsRun": false,
"logging": true,
"entities": [
"User"
],
"migrations": [
"1626771964722-UserCreate"
]
},
"logger": {
"options": true
},
"driver": {
"isReplicated": false,
"treeSupport": true,
"supportedDataTypes": [
"int",
"integer",
"tinyint",
"smallint",
"mediumint",
"bigint",
"unsigned big int",
"int2",
"int8",
"integer",
"character",
"varchar",
"varying character",
"nchar",
"native character",
"nvarchar",
"text",
"clob",
"text",
"blob",
"real",
"double",
"double precision",
"float",
"real",
"numeric",
"decimal",
"boolean",
"date",
"time",
"datetime"
],
"withLengthColumnTypes": [
"character",
"varchar",
"varying character",
"nchar",
"native character",
"nvarchar",
"text",
"blob",
"clob"
],
"spatialTypes": [],
"withPrecisionColumnTypes": [
"real",
"double",
"double precision",
"float",
"real",
"numeric",
"decimal",
"date",
"time",
"datetime"
],
"withScaleColumnTypes": [
"real",
"double",
"double precision",
"float",
"real",
"numeric",
"decimal"
],
"mappedDataTypes": {
"createDate": "datetime",
"createDateDefault": "datetime('now')",
"updateDate": "datetime",
"updateDateDefault": "datetime('now')",
"deleteDate": "datetime",
"deleteDateNullable": true,
"version": "integer",
"treeLevel": "integer",
"migrationId": "integer",
"migrationName": "varchar",
"migrationTimestamp": "bigint",
"cacheId": "int",
"cacheIdentifier": "varchar",
"cacheTime": "bigint",
"cacheDuration": "int",
"cacheQuery": "text",
"cacheResult": "text",
"metadataType": "varchar",
"metadataDatabase": "varchar",
"metadataSchema": "varchar",
"metadataTable": "varchar",
"metadataName": "varchar",
"metadataValue": "text"
},
"connection": "...",
"options": "...",
"database": "mydrivetime",
"driver": "...",
"sqlite": "...",
"databaseConnection": {}
},
"manager": {
"repositories": [],
"plainObjectToEntityTransformer": {},
"connection": "..."
},
"namingStrategy": {
"nestedSetColumnNames": {
"left": "nsleft",
"right": "nsright"
},
"materializedPathColumnName": "mpath"
},
"relationLoader": {
"connection": "..."
},
"relationIdLoader": {
"connection": "..."
},
"isConnected": true
}
The issue turned out to be a well known issue with the TypeORM entity/migrations not working when they are minified. The fix is add vue config to prevent the classnames from being minified as follows:
//vue.config.js (in the root folder)
module.exports = {
chainWebpack: config => {
if (process.env.NODE_ENV === 'production') {
config.optimization.minimizer('terser').tap((args) => {
// see https://cli.vuejs.org/guide/webpack.html#chaining-advanced
// https://cli.vuejs.org/migrating-from-v3/#vue-cli-service
// => chainWebpack for a chain override example
// https://github.com/terser/terser#minify-options for terser options
const terserOptions = args[0].terserOptions
// Avoid to mangle entities (leads to query errors)
terserOptions["keep_classnames"] = true
terserOptions["keep_fnames"] = true
// console.log(JSON.stringify(args[0], null, 2))
return args
})
}
},
// ...rest of your vue.config.js...
}
For further info, please check this github issue