capacitor-community / sqlite

Community plugin for native & electron SQLite databases
MIT License
426 stars 104 forks source link

PRAGMA table_info throws error #512

Closed rkreutzer closed 3 months ago

rkreutzer commented 3 months ago

Describe the bug When executing a query "PRAGMA table_info("xxxx");", it throws error "Error: Run: error code 100: another row available"

While there is a workaround to query sqlite_master for the table name, the synchronize function calls PRAGMA table_xinfo, which also fails with the same error.

To Reproduce Connect to a database and run 'await db.query('PRAGMA table_info("xxxx");')

Expected behavior No error message is given and it returns an array

Additional context This was working in version 5.0.6 and likely in version 5.4

jepiqueau commented 3 months ago

@rkreutzer OK it seems to be that from the implementation of RETURNING mode. In fact you must not use db.query but use db.run command. Which must not producteur the error. As i already said db.query is only for SELECT statements hope this will answer

rkreutzer commented 3 months ago

I'm using TypeORM in an Ionic/Angular app, so db.run is not a callable unction. It appears that any db.query PRAGMA statements are converted to run functions internally, and db..query("PRAGMA foreign_keys=OFF;") works fine. However db.synchronize runs a bunch of PRAGMA index_list, table_xinfo and foreign_key_list statements, all of which fail with this error.

jepiqueau commented 3 months ago

@rkreutzer In the typeOrm driver QueryRunner starting by

Can you share your code or a simple repro, i am not too much familiar with typeOrm. i am currently busy working on trying to fix the bug "The jeep-sqlite element is not present in the DOM!" for the web part of the plugin to allow this command npx typeorm-ts-node-esm migration:generate. Is this something that you see as beneficial ?

rkreutzer commented 3 months ago

After more research, backing typeorm to 0.3.17 works. PRAGMA was added to the run method in 0.3.20, and if I delete PRAGMA from CapacitorQueryRunner, it works. The issue was reported a few weeks ago on their repo at https://github.com/typeorm/typeorm/pull/10273#issuecomment-1880975903

As to the migrate:generate question, I don't think that it affects my app.

jepiqueau commented 3 months ago

@rkreutzer i reproduce the issue, PRAGMA should not be put in the list of the run method in the typeorm driver, it works well for query method. i am looking if i can implemented in the run method.

jepiqueau commented 3 months ago

@rkreutzer it has been added on last January 3 PR#10273 "resolve circular dependency when using vite" by AlexMesser and proposed by Vorujack in last August the best is perhaps that you question them on this and what are the reason they hadd to had PRAGMA to the list of run method. As i said it is not correct so someone must remove it this will imply quite o lot of changes in my code for no reason as db.query for PRAGMA works well. Can you deal that with them please.

rkreutzer commented 3 months ago

I created https://github.com/typeorm/typeorm/issues/10687 in the TypeORM repo.

jepiqueau commented 3 months ago

@rkreutzer thank you for this

jepiqueau commented 3 months ago

@rkreutzer what you can do meanwhile is to create a scripts folder in your app and a file modify-typeorm.cjs containing

const fs = require('fs');

const filePath = './node_modules/typeorm/driver/capacitor/CapacitorQueryRunner.js';
const lineToModify = 61;
const replacementText = '    else if (["INSERT", "UPDATE", "DELETE"].indexOf(command) !== -1) {';

fs.readFile(filePath, 'utf8', (err, data) => {
  if (err) {
    console.error('Error reading file:', err);
    return;
  }

  // Split data by line
  const lines = data.split('\n');

  // Modify the specific line
  if (lines.length >= lineToModify) {
    lines[lineToModify - 1] = replacementText; // Line numbers are 1-based
  } else {
    console.error('Line number to modify is out of range.');
    return;
  }

  // Join lines back together
  const modifiedData = lines.join('\n');

  // Write the modified data back to the file
  fs.writeFile(filePath, modifiedData, 'utf8', (err) => {
    if (err) {
      console.error('Error writing file:', err);
      return;
    }
    console.log('File modified successfully.');
  });
});

add in package.json a script postinstall like this

"scripts": {
...
    "postinstall": "node ./scripts/modify-typeorm.cjs"
  },

and the you run the script postinstall prior to build

npm run postinstall