Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add mysql json support (wip) #271

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Add mysql json support (wip) #271

wants to merge 1 commit into from

Conversation

kule
Copy link

@kule kule commented Sep 14, 2018

This is an initial stab at getting mysql json tests passing (related #226).

This isn't ready for use yet and is more to get discussion going - this will break postgres specs as I've commented out pg_opts for now.

Things that needed changing to get the mysql tests passing:

  • Rather then 'en', json keys must be in the format '$.en'.
  • Because dashes aren't valid ECMAScript identifiers these must be escaped so '$.en-GB' needs to become '$."en-GB"'
  • You can't have a default value on a json column
  • The first set of like/ilike specs (with case-insensitivity) fail for mysql because the json appears to be case-sensitive regardless of collation (EDIT: so currently I've skipped these for mysql). Would have to use lower() by the looks of things...

TODO - would appreciate some thoughts or ideas on these:

  • Uncomment pg_opts and refactor so mysql_opts can be loaded too
  • Refactor quoting - this'll probably need escaping properly
  • Decide whether to ignore or fix the json case-insensitivity tests

@shioyama
Copy link
Owner

Thanks very much! Really happy to see this, looks great. I'll have a look in the next few days and get back about where to go from here.

@kule
Copy link
Author

kule commented Sep 14, 2018

Cool I started looking at the changes required for travis - it’ll need changing to trusty with sudo required to get MySQL 5.7 (which has json support).

Looks like things don’t play so nice in rails 4 either so I’ll have a look see what’s needed.

@shioyama
Copy link
Owner

Looks like things don’t play so nice in rails 4 either so I’ll have a look see what’s needed.

Don't worry about that, it's absolutely fine not to support Rails 4 on this feature.

You can use the metadata rails_version_geq: 5.0 to mark specs for mysql json that fail in Rails 4, like this:

it "deletes keys with nil values when saving", rails_version_geq: '5.0' do
backend.write(:en, "foo")
expect(instance.read_attribute(column1)).to match_hash({ en: "foo" })
backend.write(:en, nil)
expect(instance.read_attribute(column1)).to match_hash({ en: nil })
instance.save
expect(backend.read(:en)).to eq(nil)
expect(instance.read_attribute(column1)).to match_hash({})
end

@shioyama shioyama self-requested a review September 15, 2018 07:49
@shioyama
Copy link
Owner

Because dashes aren't valid ECMAScript identifiers these must be escaped so '$.en-GB' needs to become '$."en-GB"'

I believe underscore is allowed as an identifier, so couldn't we use '$.en_gb' instead? i.e. Mobility.normalize_locale(locale).

You can't have a default value on a json column

Hmm. With postgres you can set the deafault to an empty hash, is this not possible with MySQL? It makes things slightly simpler if you can do this.

The first set of like/ilike specs (with case-insensitivity) fail for mysql because the json appears to be case-sensitive regardless of collation (EDIT: so currently I've skipped these for mysql). Would have to use lower() by the looks of things...

That's totally fine!

@shioyama
Copy link
Owner

Uncomment pg_opts and refactor so mysql_opts can be loaded too

I think we should probably namespace the pg-specific constants, maybe we can just prepend Pg to their names?

i.e. instead of Mobility::Arel::Nodes::Json, we call that Mobility::Arel::Nodes::PgJson, etc? Then you could also define Mobility::Arel::Nodes::MysqlJson maybe? Not sure about the naming.

def initialize column, locale, attr
super(Arel::Nodes::JsonDashArrow.new(column, locale), attr)
end
end
Copy link
Owner

Choose a reason for hiding this comment

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

It's great that you're trying to support a container format for MySQL Json, but I think it will make things a bit complicated for this first PR. How about removing this and leaving it for another PR later?

@shioyama
Copy link
Owner

@kule I made some quick comments, let me know what you think. I'll try to have another look later this week.

@kule
Copy link
Author

kule commented Sep 19, 2018

@shioyama thanks I'll see if I can get time towards the end of the week to make these changes.

RE default values - no it's a limitation with MySQL unfortunately: https://dev.mysql.com/doc/refman/8.0/en/json.html (about 4th paragraph down). MySQL has the same issue with TEXT & BLOB fields, I think it's due to the way it stores them.

@shioyama
Copy link
Owner

Great thanks!

it’ll need changing to trusty with sudo required to get MySQL 5.7 (which has json support).

Also, for this yes please update .travis.yml to use sudo so the tests run. I'm not sure if we'll actually leave this when merging since it will slow down the whole suite, but anyway first let's make sure these changes pass specs. I don't know if there is a way with travis to run some specs with sudo and others without, I suspect not...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants