Vincit / objection.js

An SQL-friendly ORM for Node.js
https://vincit.github.io/objection.js
MIT License
7.25k stars 636 forks source link

Cordova SQLite / Websql in-browser support #6

Closed jimthedev closed 8 years ago

jimthedev commented 9 years ago

Hello there.

We have relational data that we would like to be able to represent in the same way on both the server and client. The reason we want it to work in the client is that our app works offline (with a custom sync solution). It would be absolutely amazing if this library was tested again the cordova sqlite implementation and the related websql browser equivalent. Would you ever consider this kind of thing as a goal of this project or is this kind of thing out of scope?

koskimas commented 9 years ago

Hi,

websql is already supported by knex which we use for all query building and connection handling. And since websql is basically sqlite, moron.js already has tests for it. Assuming cordova's websql implementation follows standards things should just work.

The problem is running moron.js in the browser. I'm pretty sure this cannot be done at the moment even if you use browserify. I would have to make a browser build.

If I get more requests like this in the future I will certainly consider the browser build. Until then I'll probably concentrate on other features.

mparpaillon commented 9 years ago

That would be great indeed

koskimas commented 9 years ago

It turns out that all packages moron.js uses are browser compatible. You can try running it in the browser using browserify. First create a file moron-browser.js to the root folder of moron.js with contents:

window.moron = require('./moron.js');

Then install browserify:

npm install -g browserify

And then run it

browserify moron-browser.js -o moron-bundle.js

The bundle can be used in a web page:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>moron.js</title>
  <script src="lodash.js"></script>
  <script src="bluebird.js"></script>
  <script src="knex.js"></script>
  <script src="moron-bundle.js"></script>
  <script>
    var knex = Knex({
      client: 'websql',
      name: 'test.db',
      version: '1.0',
      // Disable pool.
      pool: {
        max: 0,
        min: 0
      }
    });

    function Test() {
      moron.Model.apply(this, arguments);
    }

    moron.Model.extend(Test);
    Test.tableName = 'Test';
    Test.knex(knex);

    knex.schema.createTable('Test', function (table) {
      table.bigincrements('id');
      table.string('text');
    }).catch(function (err) {
      // We get here if the table already exists.
    }).then(function () {
      return Test.query().insert({text: 'test 1'});
    }).then(function () {
      return Test.query();
    }).then(function (models) {
      console.log(models);
    }).catch(function (err) {
      console.log(err);
    });
  </script>
</head>
<body>

</body>
</html>

Knex throws an error with the example above. Don't know if there is something wrong with my code, or if it is a bug in knex.

jimthedev commented 9 years ago

@koskimas Interesting. Thanks for looking at it. I'll take a peak later today. Excited!

jimthedev commented 9 years ago

Potentially related to Knex error: https://github.com/tgriesser/knex/issues/877

mparpaillon commented 9 years ago

I'll definitely give this a try :+1:

Thanks !

koskimas commented 9 years ago

There are two bugs in knex, both described in the issue @jimthedev attached. Until they are fixed you can get things running by using the version 2.9.27 of bluebird and by replacing the line:

err.message = SqlString.format(obj.sql, obj.bindings) + ' - ' + err.message;

with

try {
  err.message = SqlString.format(obj.sql, obj.bindings) + ' - ' + err.message;
} catch (ignore) {
   // `message` is sometimes a getter.
}

in the knex.js file. I also updated the example I posted before.

jimthedev commented 9 years ago

@koskimas Did you create a PR with the fix in Knex? Would this work long term?

koskimas commented 9 years ago

Sorry, I forgot to answer this.

I didn't create a PR because I'm not familiar enough with knex's internals. My solution was a hack to make it work for our tests.

Unfortunately I cannot give any guarantees about this since I don't have tests for browsers. Making the integration tests run also on browsers seems like a lot of work, and I don't think I have time to do that any time soon.

kapouer commented 8 years ago

None of my business, but i suspect this issue would better be labelled as "won't fix" instead of being closed.

koskimas commented 8 years ago

I can add the wontfix label, but I don't want to keep these issues lying around forever when no one seems to be interested in them.

jmwolfe commented 7 years ago

@jimthedev , did you ever get this working? I'm still looking for the best ORM for CordovaSQLite and this solution looked promising, except all the working around of the Knex defects.