Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add support for MySQL #47

Merged
merged 1 commit into from
Mar 1, 2017
Merged

Add support for MySQL #47

merged 1 commit into from
Mar 1, 2017

Conversation

ricardogama
Copy link
Collaborator

This PR adds support for MySQL which does not parse JSON columns on fetch.

Closes #46

@ricardogama ricardogama force-pushed the feature/mysql-support branch 2 times, most recently from 1b04b92 to b7a29d7 Compare January 19, 2017 13:18
src/index.js Outdated
@@ -49,19 +49,22 @@ function parse(model, response, options = {}) {
export default Bookshelf => {
const Model = Bookshelf.Model.prototype;
const client = Bookshelf.knex.client.config.client;
const parseOnFetch = client === 'sqlite' || client === 'sqlite3';
const handleOnSaving = client !== 'mysql';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disabling serialization on save for mysql breaks in my project, so I'm inclined to think that you should not do this. It seems like it is necessary to allow the plugin to do its thing both on save and fetch for mysql. Disabling on save when trying to save a model with an object in place of the expected JSON string results in the following error: Error: ER_WRONG_VALUE_COUNT_ON_ROW: Column count doesn't match value count at row 1. So the json column / object still needs to be serialized/stringified when mysql is the client.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's weird, if you see the test suite I added for MySQL, all tests passed on saving without registering a JSON column, which does not happen for other clients, and that's why we didn't tested against MySQL until now.

Can you provide a snippet with real data showing the plugin breaking? Turning on debug on the knexfile would help.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing. Disabling the stringify on save results in the following:

{ method: 'insert',
  options: {},
  timeout: false,
  cancelOnTimeout: false,
  bindings: 
   [ { street: '1234 Road Ave',
       city: 'Town',
       zip: 32309,
       someOtherField: 'data' },
     Thu Jan 19 2017 09:39:17 GMT-0500 (EST),
     'test@example.com',
     '72261b8c-752f-4196-96b7-6b115d921f21',
     'Test User',
     'test-realm',
     Thu Jan 19 2017 09:39:17 GMT-0500 (EST) ],
  __knexQueryUid: '9ed6cc46-ec48-465a-9df2-0d7b1299df9c',
  sql: 'insert into `users` (`address`, `created_at`, `email`, `id`, `name`, `phoneNumber`, `realm`, `updated_at`) values (?, ?, ?, ?, ?, DEFAULT, ?, ?)' }
Error: ER_WRONG_VALUE_COUNT_ON_ROW: Column count doesn't match value count at row 1

address is the field that should be stringified.

Enabling stringify on save works great:

{ method: 'insert',
  options: {},
  timeout: false,
  cancelOnTimeout: false,
  bindings: 
   [ '{"street":"1234 Road Ave","city":"Town","zip":32309,"someOtherField":"data"}',
     Thu Jan 19 2017 09:45:29 GMT-0500 (EST),
     'test@example.com',
     'dc608afb-3731-4d31-9a07-73cb97cee673',
     'Test User',
     'test-realm',
     Thu Jan 19 2017 09:45:29 GMT-0500 (EST) ],
  __knexQueryUid: '4b5508eb-c3a0-4755-b8f0-6b053d98ec56',
  sql: 'insert into `users` (`address`, `created_at`, `email`, `id`, `name`, `phoneNumber`, `realm`, `updated_at`) values (?, ?, ?, ?, ?, DEFAULT, ?, ?)' }

The address gets stringified and appropriately inserted into the TEXT field in the mysql db.

Copy link
Collaborator Author

@ricardogama ricardogama Jan 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm struggling to reproduce your query, what's the default value for phoneNumber? Can you provide the full table schema? Also, if you set a phoneNumber on the model do you get the same error?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also provide your knex and MySQL versions as well.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure here's the whole schema:

knex.schema.createTableIfNotExists('users', (table) => {
  table.uuid('id').primary().notNullable()
  table.timestamps(false, true)
  table.string('name').notNullable()
  table.string('realm').notNullable()
  table.string('email').notNullable()
  table.string('phoneNumber')
  table.json('address')
  table.unique(['realm', 'email'])
})

Using knex ^0.12.6 and mysql ^2.12.0

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For what it's worth, my suggestion would be to simply remove handleOnSaving and the associated logic for it. In my experiences so far, that gets everything working perfectly.

Copy link
Collaborator Author

@ricardogama ricardogama Jan 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing is that I would like to reproduce the error, adding a test where a query fails without using the plugin and another fixing it with the plugin as it's our convention.

Anyway if I can't do that I'll remove that constraint and turn on the parsing on saving across all clients as you suggested, although tests on MySQL will get weird.

I currently don't have time to investigate further, can you please use the hotfix/mysql-support branch in the meantime?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah absolutely. Thanks for setting up the hotfix branch. :)

.travis.yml Outdated
- cp test/postgres/knexfile.js.dist test/postgres/knexfile.js
- cp test/sqlite/knexfile.js.dist test/sqlite/knexfile.js
- psql -U postgres -c 'create database "bookshelf-json-columns";'
- mysql -e "create database \`bookshelf-json-columns\`;" -uroot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sort.

README.md Outdated
@@ -75,12 +75,12 @@ bookshelf.Model.extend({

Contributions are welcome and greatly appreciated, so feel free to fork this repository and submit pull requests.

**bookshelf-json-columns** supports PostgreSQL and SQLite3. You can find test suites for each of these database engines in the *test/postgres* and *test/sqlite* folders.
**bookshelf-json-columns** supports PostgreSQL, SQLite3 and MySQL. You can find test suites for each of these database engines in the *test/postgres*, *test/sqlite* and *test/mysql* folders.

Copy link
Contributor

@abelsoares abelsoares Mar 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about ... You can find test suites for each of these database engines in the *test* folder.

I think it's enough.

README.md Outdated

### Setting up

- Fork and clone the **bookshelf-json-columns** repository.
- Duplicate *test/postgres/knexfile.js.dist* and *test/sqlite/knexfile.js.dist* files and update them to your needs.
- Duplicate *test/postgres/knexfile.js.dist*, *test/sqlite/knexfile.js.dist* and *test/mysql/knexfile.js.dist* files and update them to your needs.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, in relation to the comment above: Duplicate each *.dist* database engine test file and update them to your needs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, please review.

@abelsoares abelsoares merged commit fd4c1a5 into master Mar 1, 2017
@abelsoares abelsoares deleted the feature/mysql-support branch March 1, 2017 14:52
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants