Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,11 @@ jobs:
version: 'edge'
experimental: true
exclude:
- ruby: '2.6'
database: 'mysql'
orm:
name: 'active_record'
version: '4.2'
- ruby: '2.6'
orm:
name: 'active_record'
Expand Down
14 changes: 7 additions & 7 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ namespace :db do
desc "Set up the database schema"
task up: :setup do
orm = ENV['ORM']
return unless orm

require orm
require "database"
DB = Mobility::Test::Database.connect(orm)
require "#{orm}/schema"
Mobility::Test::Schema.up
if orm
require orm
require "database"
DB = Mobility::Test::Database.connect(orm)
require "#{orm}/schema"
Mobility::Test::Schema.up
end
end

desc "Drop and recreate the database schema"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module Backends

=end
module ActiveRecord
class PgHash
class DbHash
include ActiveRecord
include HashValued

Expand All @@ -33,10 +33,11 @@ def each_locale
end

def translations
model[column_name] ||= {}
model[column_name]
end
end
private_constant :PgHash
private_constant :DbHash
end
end
end
4 changes: 2 additions & 2 deletions lib/mobility/backends/active_record/hstore.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require 'mobility/backends/active_record/pg_hash'
require 'mobility/backends/active_record/db_hash'
require 'mobility/plugins/arel/nodes/pg_ops'

module Mobility
Expand All @@ -11,7 +11,7 @@ module Backends

=end
module ActiveRecord
class Hstore < PgHash
class Hstore < DbHash
# @!group Backend Accessors
# @!macro backend_reader
# @!method read(locale, options = {})
Expand Down
6 changes: 3 additions & 3 deletions lib/mobility/backends/active_record/json.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
require 'mobility/backends/active_record/pg_hash'
require 'mobility/plugins/arel/nodes/pg_ops'
require 'mobility/backends/active_record/db_hash'
require 'mobility/plugins/arel/nodes/json_ops'

module Mobility
module Backends
Expand All @@ -11,7 +11,7 @@ module Backends

=end
module ActiveRecord
class Json < PgHash
class Json < DbHash
# @!group Backend Accessors
#
# @!method read(locale, **options)
Expand Down
4 changes: 2 additions & 2 deletions lib/mobility/backends/active_record/jsonb.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require 'mobility/backends/active_record/pg_hash'
require 'mobility/backends/active_record/db_hash'
require 'mobility/plugins/arel/nodes/pg_ops'

module Mobility
Expand All @@ -11,7 +11,7 @@ module Backends

=end
module ActiveRecord
class Jsonb < PgHash
class Jsonb < DbHash
# @!group Backend Accessors
#
# @!method read(locale, **options)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module Backends

=end
module Sequel
class PgHash
class DbHash
include Sequel
include HashValued

Expand Down Expand Up @@ -52,7 +52,7 @@ def translations
columns.each { |column| default_values[column] = {} }
end
end
private_constant :PgHash
private_constant :DbHash
end
end
end
4 changes: 2 additions & 2 deletions lib/mobility/backends/sequel/hstore.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require 'mobility/backends/sequel/pg_hash'
require 'mobility/backends/sequel/db_hash'

Sequel.extension :pg_hstore, :pg_hstore_ops

Expand All @@ -12,7 +12,7 @@ module Backends

=end
module Sequel
class Hstore < PgHash
class Hstore < DbHash
# @!group Backend Accessors
# @!macro backend_reader
# @!method read(locale, options = {})
Expand Down
4 changes: 2 additions & 2 deletions lib/mobility/backends/sequel/json.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true
require 'mobility/backends/sequel/pg_hash'
require 'mobility/backends/sequel/db_hash'

Sequel.extension :pg_json, :pg_json_ops

Expand All @@ -13,7 +13,7 @@ module Backends

=end
module Sequel
class Json < PgHash
class Json < DbHash
# @!group Backend Accessors
#
# @!method read(locale, options = {})
Expand Down
4 changes: 2 additions & 2 deletions lib/mobility/backends/sequel/jsonb.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true
require 'mobility/backends/sequel/pg_hash'
require 'mobility/backends/sequel/db_hash'

Sequel.extension :pg_json, :pg_json_ops

Expand All @@ -13,7 +13,7 @@ module Backends

=end
module Sequel
class Jsonb < PgHash
class Jsonb < DbHash
# @!group Backend Accessors
#
# @!method read(locale, **options)
Expand Down
76 changes: 76 additions & 0 deletions lib/mobility/plugins/arel/nodes/json_ops.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# frozen-string-literal: true
require "mobility/plugins/arel"

module Mobility
module Plugins
module Arel
module Nodes
%w[
JsonDashArrow
JsonDashDoubleArrow
].each do |name|
const_set name, (Class.new(Binary) do
include ::Arel::Predications
include ::Arel::OrderPredications
include ::Arel::AliasPredication
include MobilityExpressions

def lower
super self
end
end)
end

class Json < JsonDashDoubleArrow; end

class JsonContainer < Json
def initialize column, locale, attr
super(Nodes::JsonDashArrow.new(column, locale), attr)
end
end
end

module Visitors
module PostgreSQL
def visit_Mobility_Plugins_Arel_Nodes_JsonDashArrow o, a
json_infix o, a, '->'
end

def visit_Mobility_Plugins_Arel_Nodes_JsonDashDoubleArrow o, a
json_infix o, a, '->>'
end

private

def json_infix o, a, opr
visit(Nodes::Grouping.new(::Arel::Nodes::InfixOperation.new(opr, o.left, o.right)), a)
end
end

module MySQL
def visit_Mobility_Plugins_Arel_Nodes_JsonDashArrow o, a
json_infix o, a, '->'
end

def visit_Mobility_Plugins_Arel_Nodes_JsonDashDoubleArrow o, a
# for MySQL we need to re-quote the JSON key name, otherwise it will break on keys like `pt-BR`
# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_json-inline-path
unless o.right.value.to_s.start_with?('$.')
o.right = o.right.class.new(%Q($."#{o.right.value}"))
end
json_infix o, a, '->>'
end

private

def json_infix o, a, opr
visit(Nodes::Grouping.new(::Arel::Nodes::InfixOperation.new(opr, o.left, o.right)), a)
end
end
end

::Arel::Visitors::PostgreSQL.include Visitors::PostgreSQL
::Arel::Visitors::MySQL.include Visitors::MySQL
end
end
end
18 changes: 0 additions & 18 deletions lib/mobility/plugins/arel/nodes/pg_ops.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ module Plugins
module Arel
module Nodes
%w[
JsonDashArrow
JsonDashDoubleArrow
JsonbDashArrow
JsonbDashDoubleArrow
JsonbQuestion
Expand Down Expand Up @@ -72,14 +70,6 @@ def eq other
end
end

class Json < JsonDashDoubleArrow; end

class JsonContainer < Json
def initialize column, locale, attr
super(Nodes::JsonDashArrow.new(column, locale), attr)
end
end

class JsonbContainer < Jsonb
def initialize column, locale, attr
@column, @locale = column, locale
Expand All @@ -93,14 +83,6 @@ def eq other
end

module Visitors
def visit_Mobility_Plugins_Arel_Nodes_JsonDashArrow o, a
json_infix o, a, '->'
end

def visit_Mobility_Plugins_Arel_Nodes_JsonDashDoubleArrow o, a
json_infix o, a, '->>'
end

def visit_Mobility_Plugins_Arel_Nodes_JsonbDashArrow o, a
json_infix o, a, '->'
end
Expand Down
17 changes: 13 additions & 4 deletions spec/active_record/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,21 +79,30 @@ def up
t.timestamps null: false
end

if ENV['DB'] == 'postgres'
create_table "jsonb_posts" do |t|
t.jsonb :my_title_i18n, default: {}
t.jsonb :my_content_i18n, default: {}
if ENV['DB'] == 'mysql'
create_table "json_posts" do |t|
t.json :my_title_i18n
t.json :my_content_i18n
t.boolean :published
t.timestamps null: false
end
end

if ENV['DB'] == 'postgres'
create_table "json_posts" do |t|
t.json :my_title_i18n, default: {}
t.json :my_content_i18n, default: {}
t.boolean :published
t.timestamps null: false
end

create_table "jsonb_posts" do |t|
t.jsonb :my_title_i18n, default: {}
t.jsonb :my_content_i18n, default: {}
t.boolean :published
t.timestamps null: false
end

create_table "container_posts" do |t|
t.jsonb :translations, default: {}
t.boolean :published
Expand Down
4 changes: 2 additions & 2 deletions spec/mobility/backends/active_record/json_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

return unless defined?(ActiveRecord)

describe "Mobility::Backends::ActiveRecord::Json", orm: :active_record, db: :postgres, type: :backend do
describe "Mobility::Backends::ActiveRecord::Json", orm: :active_record, db: [:mysql, :postgres], type: :backend do
require "mobility/backends/active_record/json"

before { stub_const 'JsonPost', Class.new(ActiveRecord::Base) }
Expand Down Expand Up @@ -30,7 +30,7 @@
post = JsonPost.create!
post.reload

expect(post.my_title_i18n).to eq({})
expect([nil, {}]).to include(post.my_title_i18n)
expect(post.changes).to eq({})
end

Expand Down
4 changes: 2 additions & 2 deletions spec/mobility/plugins/sequel/query_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

context "default query scope" do
it "defines query scope" do
expect(model_class.i18n).to eq(described_class.build_query(model_class, Mobility.locale))
expect(model_class.i18n.sql).to eq(described_class.build_query(model_class, Mobility.locale).sql)
end
end

Expand All @@ -29,7 +29,7 @@
end

it "defines query scope" do
expect(model_class.foo).to eq(described_class.build_query(model_class, Mobility.locale))
expect(model_class.foo.sql).to eq(described_class.build_query(model_class, Mobility.locale).sql)
expect { model_class.i18n }.to raise_error(NoMethodError)
end
end
Expand Down
11 changes: 9 additions & 2 deletions spec/support/shared_examples/querying_examples.rb
Original file line number Diff line number Diff line change
Expand Up @@ -551,8 +551,15 @@ def query(*args, **kwargs, &block); model_class.i18n(*args, **kwargs, &block); e
it "includes partial string matches" do
foobar = model_class.create(a1 => "foObar")
barfoo = model_class.create(a1 => "barfOo")
expect(query { __send__(a1).matches("foo%") }).to match_array([i[0], *i[5..6], foobar])
expect(query { __send__(a1).matches("%foo") }).to match_array([i[0], *i[5..6], barfoo])

if backend == Mobility::Backends::ActiveRecord::Json && ENV['DB'] == 'mysql'
# MySQL JSON columns are case sensitive
expect(query { __send__(a1).matches("foO%") }).to match_array([foobar])
expect(query { __send__(a1).matches("%fOo") }).to match_array([barfoo])
else
expect(query { __send__(a1).matches("foo%") }).to match_array([i[0], *i[5..6], foobar])
expect(query { __send__(a1).matches("%foo") }).to match_array([i[0], *i[5..6], barfoo])
end
end

if ENV['DB'] == 'postgres' && ::ActiveRecord::VERSION::STRING >= '5.0'
Expand Down