chrono_model 0.13.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.travis.yml +8 -8
- data/README.md +2 -2
- data/chrono_model.gemspec +1 -1
- data/gemfiles/rails_5.0.gemfile +0 -1
- data/gemfiles/rails_5.1.gemfile +0 -1
- data/gemfiles/rails_5.2.gemfile +6 -0
- data/lib/active_record/connection_adapters/chronomodel_adapter.rb +1 -5
- data/lib/chrono_model/adapter.rb +4 -4
- data/lib/chrono_model/patches.rb +30 -29
- data/lib/chrono_model/time_machine.rb +26 -34
- data/lib/chrono_model/version.rb +1 -1
- data/spec/aruba/migrations_spec.rb +4 -18
- data/spec/aruba/rake_task_spec.rb +4 -4
- data/spec/json_ops_spec.rb +5 -5
- data/spec/spec_helper.rb +0 -3
- data/spec/support/aruba.rb +0 -5
- data/spec/support/matchers/function.rb +1 -1
- data/spec/support/matchers/table.rb +3 -3
- data/spec/time_machine_spec.rb +1 -1
- metadata +5 -11
- data/gemfiles/rails_4.2.gemfile +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2697fea79973f57287cdb45ffa3bc3e5ecac4b3ad0c9b98b30ac77412a39727e
|
4
|
+
data.tar.gz: 2d683ca63fccf590d3f90e0196e8c3392e1033d726181a772ea80fba9acb8515
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fbe2f67c78f27a89c007007dcf2b29e40ddafee336191be41fa05e40cea2f0cc5bbf0c509c46facc756ff03f212b203b4f7824ce8ec7e7d376610f1b03797204
|
7
|
+
data.tar.gz: 89f588e6b34b4b841e2a6f1b5bda6d7c9ee55a497134d738be53e9c08db6f3bef87a061421860524ada85f370e1c1e492ef0b54488cfda5bacdfe7eb84277de6
|
data/.travis.yml
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
rvm:
|
2
|
-
- 2.2.7
|
3
2
|
- 2.3
|
4
3
|
- 2.4
|
4
|
+
- 2.5
|
5
5
|
|
6
6
|
gemfile:
|
7
|
-
- gemfiles/rails_4.2.gemfile
|
8
7
|
- gemfiles/rails_5.0.gemfile
|
9
8
|
- gemfiles/rails_5.1.gemfile
|
9
|
+
- gemfiles/rails_5.2.gemfile
|
10
10
|
|
11
|
-
matrix:
|
12
|
-
exclude:
|
13
|
-
- rvm: 2.4
|
14
|
-
gemfile: gemfiles/rails_4.2.gemfile
|
11
|
+
#matrix:
|
12
|
+
# exclude:
|
13
|
+
# - rvm: 2.4
|
14
|
+
# gemfile: gemfiles/rails_4.2.gemfile
|
15
15
|
|
16
16
|
sudo: false
|
17
17
|
|
@@ -19,9 +19,9 @@ language: ruby
|
|
19
19
|
cache: bundler
|
20
20
|
|
21
21
|
addons:
|
22
|
-
postgresql: "9.
|
22
|
+
postgresql: "9.6"
|
23
23
|
apt:
|
24
|
-
packages: postgresql-plpython-9.
|
24
|
+
packages: postgresql-plpython-9.6
|
25
25
|
code_climate:
|
26
26
|
repo_token: dedfb7472ee410eec459bff3681d9a8fd8dd237e9bd7e8675a7c8eb7e253bba9
|
27
27
|
|
data/README.md
CHANGED
@@ -65,8 +65,8 @@ All timestamps are _forcibly_ stored in as UTC, bypassing the
|
|
65
65
|
|
66
66
|
## Requirements
|
67
67
|
|
68
|
-
* Ruby >= 2.
|
69
|
-
* Active Record
|
68
|
+
* Ruby >= 2.3
|
69
|
+
* Active Record >= 5.0. See the [detailed supported versions matrix on travis](https://travis-ci.org/ifad/chronomodel)
|
70
70
|
* PostgreSQL >= 9.3
|
71
71
|
* The `btree_gist` PostgreSQL extension
|
72
72
|
* The `plpython` PostgreSQL extension if you have *JSON* (*not* JSONB) columns
|
data/chrono_model.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = ChronoModel::VERSION
|
17
17
|
|
18
|
-
gem.add_dependency 'activerecord', '>=
|
18
|
+
gem.add_dependency 'activerecord', '>= 5.0.0'
|
19
19
|
gem.add_dependency "pg"
|
20
20
|
gem.add_dependency "multi_json"
|
21
21
|
|
data/gemfiles/rails_5.0.gemfile
CHANGED
data/gemfiles/rails_5.1.gemfile
CHANGED
@@ -17,11 +17,7 @@ module ActiveRecord
|
|
17
17
|
conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database]
|
18
18
|
|
19
19
|
# Forward only valid config params to PG::Connection.connect.
|
20
|
-
valid_conn_param_keys =
|
21
|
-
VALID_CONN_PARAMS
|
22
|
-
else
|
23
|
-
PG::Connection.conndefaults_hash.keys + [:requiressl]
|
24
|
-
end
|
20
|
+
valid_conn_param_keys = PG::Connection.conndefaults_hash.keys + [:requiressl]
|
25
21
|
conn_params.slice!(*valid_conn_param_keys)
|
26
22
|
|
27
23
|
# The postgres drivers don't allow the creation of an unconnected PG::Connection object,
|
data/lib/chrono_model/adapter.rb
CHANGED
@@ -35,8 +35,8 @@ module ChronoModel
|
|
35
35
|
return super unless options[:temporal]
|
36
36
|
|
37
37
|
if options[:id] == false
|
38
|
-
logger.warn "
|
39
|
-
logger.warn "
|
38
|
+
logger.warn "ChronoModel: Temporal Temporal tables require a primary key."
|
39
|
+
logger.warn "ChronoModel: Adding a `__chrono_id' primary key to #{table_name} definition."
|
40
40
|
|
41
41
|
options[:id] = '__chrono_id'
|
42
42
|
end
|
@@ -511,7 +511,7 @@ module ChronoModel
|
|
511
511
|
end
|
512
512
|
end
|
513
513
|
|
514
|
-
def initialize_type_map(type_map)
|
514
|
+
def initialize_type_map(m = type_map)
|
515
515
|
super.tap do
|
516
516
|
ar_type = type_map.fetch(TSRange::OID)
|
517
517
|
cm_type = TSRange.new(ar_type.subtype, ar_type.type)
|
@@ -601,7 +601,7 @@ module ChronoModel
|
|
601
601
|
upgrade_from_legacy(table_name)
|
602
602
|
logger.info "ChronoModel: legacy #{table_name} upgrade complete"
|
603
603
|
else
|
604
|
-
logger.info "ChronoModel: upgrading #{table_name} from #{
|
604
|
+
logger.info "ChronoModel: upgrading #{table_name} from #{version} to #{VERSION}"
|
605
605
|
chrono_create_view_for(table_name)
|
606
606
|
logger.info "ChronoModel: #{table_name} upgrade complete"
|
607
607
|
end
|
data/lib/chrono_model/patches.rb
CHANGED
@@ -6,8 +6,6 @@ module ChronoModel
|
|
6
6
|
module AsOfTimeHolder
|
7
7
|
# Sets the virtual 'as_of_time' attribute to the given time, converting to UTC.
|
8
8
|
#
|
9
|
-
# See ChronoModel::Patches::AsOfTimeHolder
|
10
|
-
#
|
11
9
|
def as_of_time!(time)
|
12
10
|
@_as_of_time = time.utc
|
13
11
|
|
@@ -16,14 +14,12 @@ module ChronoModel
|
|
16
14
|
|
17
15
|
# Reads the virtual 'as_of_time' attribute
|
18
16
|
#
|
19
|
-
# See ChronoModel::Patches::AsOfTimeHolder
|
20
|
-
#
|
21
17
|
def as_of_time
|
22
18
|
@_as_of_time
|
23
19
|
end
|
24
20
|
end
|
25
21
|
|
26
|
-
# This class supports the AR
|
22
|
+
# This class supports the AR 5.0 code that expects to receive an
|
27
23
|
# Arel::Table as the left join node. We need to replace the node
|
28
24
|
# with a virtual table that fetches from the history at a given
|
29
25
|
# point in time, we replace the join node with a SqlLiteral node
|
@@ -65,7 +61,7 @@ module ChronoModel
|
|
65
61
|
super.as_of_time!(@_as_of_time)
|
66
62
|
end
|
67
63
|
|
68
|
-
def build_arel
|
64
|
+
def build_arel(*)
|
69
65
|
return super unless @_as_of_time
|
70
66
|
|
71
67
|
super.tap do |arel|
|
@@ -85,11 +81,27 @@ module ChronoModel
|
|
85
81
|
end
|
86
82
|
end
|
87
83
|
|
88
|
-
# Build a preloader at the +as_of_time+ of this relation
|
84
|
+
# Build a preloader at the +as_of_time+ of this relation.
|
85
|
+
# Pass the current model to define Relation
|
89
86
|
#
|
90
87
|
def build_preloader
|
91
|
-
|
92
|
-
|
88
|
+
ActiveRecord::Associations::Preloader.new(
|
89
|
+
model: self.model, as_of_time: as_of_time
|
90
|
+
)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# This class is a dummy relation whose scope is only to pass around the
|
95
|
+
# as_of_time parameters across ActiveRecord call chains.
|
96
|
+
#
|
97
|
+
# With AR 5.2 a simple relation can be used, as the only required argument
|
98
|
+
# is the model. 5.0 and 5.1 require more arguments, that are passed here.
|
99
|
+
#
|
100
|
+
class AsOfTimeRelation < ActiveRecord::Relation
|
101
|
+
if ActiveRecord::VERSION::STRING.to_f < 5.2
|
102
|
+
def initialize(klass, table: klass.arel_table, predicate_builder: klass.predicate_builder, values: {})
|
103
|
+
super(klass, table, predicate_builder, values)
|
104
|
+
end
|
93
105
|
end
|
94
106
|
end
|
95
107
|
|
@@ -107,13 +119,6 @@ module ChronoModel
|
|
107
119
|
@options = options.freeze
|
108
120
|
end
|
109
121
|
|
110
|
-
# See +ActiveRecord::Associations::Preloader::NULL_RELATION+
|
111
|
-
NULL_RELATION = ActiveRecord::Associations::Preloader::NULL_RELATION
|
112
|
-
|
113
|
-
# Extend +NULL_RELATION+ by adding the +as_of_time!+ method.
|
114
|
-
# See +preload+ and +AsOfTimeHolder+.
|
115
|
-
NULL_RELATION.class.instance_eval { include AsOfTimeHolder }
|
116
|
-
|
117
122
|
# Patches the AR Preloader (lib/active_record/associations/preloader.rb)
|
118
123
|
# in order to carry around the +as_of_time+ of the original invocation.
|
119
124
|
#
|
@@ -128,22 +133,18 @@ module ChronoModel
|
|
128
133
|
# around the +as_of_time+ of the original query invocation, so that
|
129
134
|
# preloaded records are preloaded honoring the +as_of_time+.
|
130
135
|
#
|
131
|
-
# The +preload_scope+ is
|
136
|
+
# The +preload_scope+ is present only in through associations, but the
|
132
137
|
# preloader interfaces expect it to be always defined, for consistency.
|
133
138
|
#
|
134
|
-
# So, AR defines a +NULL_RELATION+ constant to pass around for the
|
135
|
-
# association types that do not have a preload_scope. It quacks like a
|
136
|
-
# Relation, and it contains only the methods that are used by the other
|
137
|
-
# preloader methods. We use this +NULL_RELATION+ to which we have added
|
138
|
-
# the `as_of_time!` holder method.
|
139
|
-
#
|
140
139
|
# For `:through` associations, the +given_preload_scope+ is already a
|
141
140
|
# +Relation+, that already has the +as_of_time+ getters and setters,
|
142
141
|
# so we use it directly.
|
143
142
|
#
|
144
143
|
def preload(records, associations, given_preload_scope = nil)
|
145
|
-
if options
|
146
|
-
preload_scope = given_preload_scope ||
|
144
|
+
if options[:as_of_time]
|
145
|
+
preload_scope = given_preload_scope ||
|
146
|
+
AsOfTimeRelation.new(options[:model])
|
147
|
+
|
147
148
|
preload_scope.as_of_time!(options[:as_of_time])
|
148
149
|
end
|
149
150
|
|
@@ -152,13 +153,13 @@ module ChronoModel
|
|
152
153
|
|
153
154
|
module Association
|
154
155
|
# Builds the preloader scope taking into account a potential
|
155
|
-
# +as_of_time+
|
156
|
-
# user
|
156
|
+
# +as_of_time+ passed down the call chain starting at the
|
157
|
+
# end user invocation.
|
157
158
|
#
|
158
159
|
def build_scope
|
159
160
|
scope = super
|
160
161
|
|
161
|
-
if preload_scope.
|
162
|
+
if preload_scope.try(:as_of_time)
|
162
163
|
scope = scope.as_of(preload_scope.as_of_time)
|
163
164
|
end
|
164
165
|
|
@@ -176,7 +177,7 @@ module ChronoModel
|
|
176
177
|
# on the join model's (:through association) one.
|
177
178
|
#
|
178
179
|
module Association
|
179
|
-
def skip_statement_cache?
|
180
|
+
def skip_statement_cache?(*)
|
180
181
|
super || _chrono_target?
|
181
182
|
end
|
182
183
|
|
@@ -9,8 +9,8 @@ module ChronoModel
|
|
9
9
|
|
10
10
|
included do
|
11
11
|
if table_exists? && !chrono?
|
12
|
-
puts
|
13
|
-
"Please use change_table :#{table_name}, :
|
12
|
+
puts "ChronoModel: #{table_name} is not a temporal table. " \
|
13
|
+
"Please use `change_table :#{table_name}, temporal: true` in a migration."
|
14
14
|
end
|
15
15
|
|
16
16
|
history = TimeMachine.define_history_model_for(self)
|
@@ -54,7 +54,7 @@ module ChronoModel
|
|
54
54
|
|
55
55
|
extend TimeMachine::HistoryMethods
|
56
56
|
|
57
|
-
scope :chronological, -> { order('lower(validity)') }
|
57
|
+
scope :chronological, -> { order(Arel.sql('lower(validity) ASC')) }
|
58
58
|
|
59
59
|
# The history id is `hid`, but this cannot set as primary key
|
60
60
|
# or temporal assocations will break. Solutions are welcome.
|
@@ -85,30 +85,16 @@ module ChronoModel
|
|
85
85
|
with_hid_pkey { super }
|
86
86
|
end
|
87
87
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
def save_with_pkey(*)
|
92
|
-
self.class.with_hid_pkey { save_without_pkey }
|
93
|
-
end
|
94
|
-
|
95
|
-
def save_with_pkey!(*)
|
96
|
-
self.class.with_hid_pkey { save_without_pkey! }
|
97
|
-
end
|
98
|
-
|
99
|
-
alias_method_chain :save, :pkey
|
100
|
-
else
|
101
|
-
def save(*)
|
102
|
-
self.class.with_hid_pkey { super }
|
103
|
-
end
|
88
|
+
def save(*)
|
89
|
+
self.class.with_hid_pkey { super }
|
90
|
+
end
|
104
91
|
|
105
|
-
|
106
|
-
|
107
|
-
|
92
|
+
def save!(*)
|
93
|
+
self.class.with_hid_pkey { super }
|
94
|
+
end
|
108
95
|
|
109
|
-
|
110
|
-
|
111
|
-
end
|
96
|
+
def update_columns(*)
|
97
|
+
self.class.with_hid_pkey { super }
|
112
98
|
end
|
113
99
|
|
114
100
|
# Returns the previous history entry, or nil if this
|
@@ -271,10 +257,13 @@ module ChronoModel
|
|
271
257
|
#
|
272
258
|
def pred(options = {})
|
273
259
|
if self.class.timeline_associations.empty?
|
274
|
-
history.order('upper(validity) DESC').offset(1).first
|
260
|
+
history.order(Arel.sql('upper(validity) DESC')).offset(1).first
|
275
261
|
else
|
276
262
|
return nil unless (ts = pred_timestamp(options))
|
277
|
-
|
263
|
+
|
264
|
+
order_clause = Arel.sql %[ LOWER(#{options[:table] || self.class.quoted_table_name}."validity") DESC ]
|
265
|
+
|
266
|
+
self.class.as_of(ts).order(order_clause).find(options[:id] || id)
|
278
267
|
end
|
279
268
|
end
|
280
269
|
|
@@ -284,9 +273,9 @@ module ChronoModel
|
|
284
273
|
def pred_timestamp(options = {})
|
285
274
|
if historical?
|
286
275
|
options[:before] ||= as_of_time
|
287
|
-
timeline(options.merge(:
|
276
|
+
timeline(options.merge(limit: 1, reverse: true)).first
|
288
277
|
else
|
289
|
-
timeline(options.merge(:
|
278
|
+
timeline(options.merge(limit: 2, reverse: true)).second
|
290
279
|
end
|
291
280
|
end
|
292
281
|
|
@@ -295,7 +284,10 @@ module ChronoModel
|
|
295
284
|
def succ(options = {})
|
296
285
|
unless self.class.timeline_associations.empty?
|
297
286
|
return nil unless (ts = succ_timestamp(options))
|
298
|
-
|
287
|
+
|
288
|
+
order_clause = Arel.sql %[ LOWER(#{options[:table] || self.class.quoted_table_name}."validity"_ DESC ]
|
289
|
+
|
290
|
+
self.class.as_of(ts).order(order_clause).find(options[:id] || id)
|
299
291
|
end
|
300
292
|
end
|
301
293
|
|
@@ -306,7 +298,7 @@ module ChronoModel
|
|
306
298
|
return nil unless historical?
|
307
299
|
|
308
300
|
options[:after] ||= as_of_time
|
309
|
-
timeline(options.merge(:
|
301
|
+
timeline(options.merge(limit: 1, reverse: false)).first
|
310
302
|
end
|
311
303
|
|
312
304
|
# Returns the current history version
|
@@ -444,9 +436,9 @@ module ChronoModel
|
|
444
436
|
|
445
437
|
def build_time_query(time, range, op = '&&')
|
446
438
|
if time.kind_of?(Array)
|
447
|
-
%[ #{range.type}(#{time.first}, #{time.last}) #{op} #{table_name}.#{range.name} ]
|
439
|
+
Arel.sql %[ #{range.type}(#{time.first}, #{time.last}) #{op} #{table_name}.#{range.name} ]
|
448
440
|
else
|
449
|
-
%[ #{time} <@ #{table_name}.#{range.name} ]
|
441
|
+
Arel.sql %[ #{time} <@ #{table_name}.#{range.name} ]
|
450
442
|
end
|
451
443
|
end
|
452
444
|
end
|
@@ -513,7 +505,7 @@ module ChronoModel
|
|
513
505
|
# Returns the history sorted by recorded_at
|
514
506
|
#
|
515
507
|
def sorted
|
516
|
-
all.order(%[ #{quoted_table_name}."recorded_at", #{quoted_table_name}."hid" ])
|
508
|
+
all.order(Arel.sql(%[ #{quoted_table_name}."recorded_at" ASC, #{quoted_table_name}."hid" ASC ]))
|
517
509
|
end
|
518
510
|
|
519
511
|
# Fetches the given +object+ history, sorted by history record time
|
data/lib/chrono_model/version.rb
CHANGED
@@ -5,10 +5,10 @@ describe 'database migrations', type: :aruba do
|
|
5
5
|
before { write_file('config/database.yml',
|
6
6
|
File.read(File.expand_path('fixtures/database_without_username_and_password.yml', __dir__))) }
|
7
7
|
|
8
|
-
before {
|
8
|
+
before { run_command_and_stop('bundle exec rails g migration CreateModels name:string') }
|
9
9
|
|
10
10
|
describe 'bundle exec rake db:migrate' do
|
11
|
-
let(:action) {
|
11
|
+
let(:action) { run_command('bundle exec rake db:migrate') }
|
12
12
|
let(:last_command) { action && last_command_started }
|
13
13
|
|
14
14
|
specify { expect(last_command).to be_successfully_executed }
|
@@ -30,21 +30,7 @@ describe 'database migrations', type: :aruba do
|
|
30
30
|
)
|
31
31
|
end
|
32
32
|
|
33
|
-
|
34
|
-
# Alter migrations and remove the version specifier for Rails < 5.0
|
35
|
-
#
|
36
|
-
if gem_version('rails') < Gem::Version.new('5.0')
|
37
|
-
Dir['spec/aruba/fixtures/migrations/56/*rb'].each do |migration|
|
38
|
-
migration = File.basename(migration)
|
39
|
-
|
40
|
-
file_mangle! "db/migrate/#{migration}" do |contents|
|
41
|
-
contents.sub(/::Migration\[\d\.\d\]/, '::Migration')
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
let(:action) { run(command) }
|
33
|
+
let(:action) { run_command(command) }
|
48
34
|
let(:regex) { /-- change_table\(:impressions, {:temporal=>true, :copy_data=>true}\)/ }
|
49
35
|
|
50
36
|
describe 'once' do
|
@@ -54,7 +40,7 @@ describe 'database migrations', type: :aruba do
|
|
54
40
|
end
|
55
41
|
|
56
42
|
describe 'twice' do
|
57
|
-
let(:last_command) {
|
43
|
+
let(:last_command) { run_command_and_stop(command) && action && last_command_started }
|
58
44
|
specify { expect(last_command).to be_successfully_executed }
|
59
45
|
specify { expect(last_command).to have_output(regex) }
|
60
46
|
end
|
@@ -5,14 +5,14 @@ require 'spec_helper'
|
|
5
5
|
#
|
6
6
|
describe 'rake tasks', type: :aruba do
|
7
7
|
describe 'bundle exec rake -T' do
|
8
|
-
before {
|
8
|
+
before { run_command_and_stop('bundle exec rake -T') }
|
9
9
|
subject { last_command_started }
|
10
10
|
|
11
11
|
it { is_expected.to have_output(/db:structure:load/) }
|
12
12
|
end
|
13
13
|
|
14
14
|
describe 'db:structure:load' do
|
15
|
-
let(:action) {
|
15
|
+
let(:action) { run_command('bundle exec rake db:structure:load') }
|
16
16
|
let(:last_command) { action && last_command_started }
|
17
17
|
|
18
18
|
context 'given a file db/structure.sql' do
|
@@ -51,7 +51,7 @@ describe 'rake tasks', type: :aruba do
|
|
51
51
|
let(:database_yml) { 'fixtures/database_without_username_and_password.yml' }
|
52
52
|
before { write_file('config/database.yml', File.read(File.expand_path(database_yml, __dir__))) }
|
53
53
|
|
54
|
-
before {
|
54
|
+
before { run_command_and_stop('bundle exec rake db:data:dump DUMP=db/test.sql') }
|
55
55
|
|
56
56
|
it { expect(last_command_started).to be_successfully_executed }
|
57
57
|
it { expect('db/test.sql').to be_an_existing_file }
|
@@ -64,7 +64,7 @@ describe 'rake tasks', type: :aruba do
|
|
64
64
|
let(:structure_sql) { 'fixtures/empty_structure.sql' }
|
65
65
|
before { write_file('db/test.sql', File.read(File.expand_path(structure_sql, __dir__))) }
|
66
66
|
|
67
|
-
before {
|
67
|
+
before { run_command_and_stop('bundle exec rake db:data:load DUMP=db/test.sql') }
|
68
68
|
|
69
69
|
it { expect(last_command_started).to be_successfully_executed }
|
70
70
|
end
|
data/spec/json_ops_spec.rb
CHANGED
@@ -14,11 +14,11 @@ describe 'JSON equality operator' do
|
|
14
14
|
ChronoModel::Json.drop
|
15
15
|
end
|
16
16
|
|
17
|
-
it { expect(adapter.select_value(%[ SELECT '{"a":1}'::json = '{"a":1}'::json ])).to eq
|
18
|
-
it { expect(adapter.select_value(%[ SELECT '{"a":1}'::json = '{"a" : 1}'::json ])).to eq
|
19
|
-
it { expect(adapter.select_value(%[ SELECT '{"a":1}'::json = '{"a":2}'::json ])).to eq
|
20
|
-
it { expect(adapter.select_value(%[ SELECT '{"a":1,"b":2}'::json = '{"b":2,"a":1}'::json ])).to eq
|
21
|
-
it { expect(adapter.select_value(%[ SELECT '{"a":1,"b":2,"x":{"c":4,"d":5}}'::json = '{"b":2, "x": { "d": 5, "c": 4}, "a":1}'::json ])).to eq
|
17
|
+
it { expect(adapter.select_value(%[ SELECT '{"a":1}'::json = '{"a":1}'::json ])).to eq true }
|
18
|
+
it { expect(adapter.select_value(%[ SELECT '{"a":1}'::json = '{"a" : 1}'::json ])).to eq true }
|
19
|
+
it { expect(adapter.select_value(%[ SELECT '{"a":1}'::json = '{"a":2}'::json ])).to eq false }
|
20
|
+
it { expect(adapter.select_value(%[ SELECT '{"a":1,"b":2}'::json = '{"b":2,"a":1}'::json ])).to eq true }
|
21
|
+
it { expect(adapter.select_value(%[ SELECT '{"a":1,"b":2,"x":{"c":4,"d":5}}'::json = '{"b":2, "x": { "d": 5, "c": 4}, "a":1}'::json ])).to eq true }
|
22
22
|
|
23
23
|
context 'on a temporal table' do
|
24
24
|
before :all do
|
data/spec/spec_helper.rb
CHANGED
@@ -17,9 +17,6 @@ require 'support/aruba'
|
|
17
17
|
|
18
18
|
puts "Testing against Active Record #{ActiveRecord::VERSION::STRING} with Arel #{Arel::VERSION}"
|
19
19
|
|
20
|
-
# Rails 5 returns a True/FalseClass
|
21
|
-
AR_TRUE, AR_FALSE = ActiveRecord::VERSION::MAJOR == 4 ? ['t', 'f'] : [true, false]
|
22
|
-
|
23
20
|
RSpec.configure do |config|
|
24
21
|
config.include(ChronoTest::Matchers::Schema)
|
25
22
|
config.include(ChronoTest::Matchers::Table)
|
data/spec/support/aruba.rb
CHANGED
@@ -31,7 +31,7 @@ module ChronoTest::Matchers
|
|
31
31
|
|
32
32
|
protected
|
33
33
|
def has_function?(name)
|
34
|
-
select_value(<<-SQL, [name], 'Check function') ==
|
34
|
+
select_value(<<-SQL, [name], 'Check function') == true
|
35
35
|
SELECT EXISTS(
|
36
36
|
SELECT 1
|
37
37
|
FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n
|
@@ -12,7 +12,7 @@ module ChronoTest::Matchers
|
|
12
12
|
schema = options[:in]
|
13
13
|
kind = options[:kind] == :view ? 'v' : 'r'
|
14
14
|
|
15
|
-
select_value(<<-SQL, [ table, schema ], 'Check table exists') ==
|
15
|
+
select_value(<<-SQL, [ table, schema ], 'Check table exists') == true
|
16
16
|
SELECT EXISTS (
|
17
17
|
SELECT 1
|
18
18
|
FROM pg_class c
|
@@ -129,7 +129,7 @@ module ChronoTest::Matchers
|
|
129
129
|
def inherits_from_temporal?
|
130
130
|
binds = ["#{history_schema}.#{table}", "#{temporal_schema}.#{table}"]
|
131
131
|
|
132
|
-
@inheritance = select_value(<<-SQL, binds, 'Check inheritance') ==
|
132
|
+
@inheritance = select_value(<<-SQL, binds, 'Check inheritance') == true
|
133
133
|
SELECT EXISTS (
|
134
134
|
SELECT 1 FROM pg_catalog.pg_inherits
|
135
135
|
WHERE inhrelid = ?::regclass::oid
|
@@ -172,7 +172,7 @@ module ChronoTest::Matchers
|
|
172
172
|
attname: connection.primary_key(table)
|
173
173
|
}
|
174
174
|
|
175
|
-
@constraint = select_value(<<-SQL, binds, 'Check Consistency Constraint') ==
|
175
|
+
@constraint = select_value(<<-SQL, binds, 'Check Consistency Constraint') == true
|
176
176
|
SELECT EXISTS (
|
177
177
|
SELECT 1 FROM pg_catalog.pg_constraint
|
178
178
|
WHERE conname = :conname
|
data/spec/time_machine_spec.rb
CHANGED
@@ -304,7 +304,7 @@ describe ChronoModel::TimeMachine do
|
|
304
304
|
|
305
305
|
context '.sorted' do
|
306
306
|
describe 'orders by recorded_at, hid' do
|
307
|
-
it { expect(foo.history.sorted.to_sql).to match(/order by .+"recorded_at", .+"hid"/i) }
|
307
|
+
it { expect(foo.history.sorted.to_sql).to match(/order by .+"recorded_at" ASC, .+"hid" ASC/i) }
|
308
308
|
end
|
309
309
|
end
|
310
310
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chrono_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcello Barnaba
|
@@ -17,20 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version:
|
21
|
-
- - "<"
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 5.2.0
|
20
|
+
version: 5.0.0
|
24
21
|
type: :runtime
|
25
22
|
prerelease: false
|
26
23
|
version_requirements: !ruby/object:Gem::Requirement
|
27
24
|
requirements:
|
28
25
|
- - ">="
|
29
26
|
- !ruby/object:Gem::Version
|
30
|
-
version:
|
31
|
-
- - "<"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 5.2.0
|
27
|
+
version: 5.0.0
|
34
28
|
- !ruby/object:Gem::Dependency
|
35
29
|
name: pg
|
36
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -217,9 +211,9 @@ files:
|
|
217
211
|
- README.sql
|
218
212
|
- Rakefile
|
219
213
|
- chrono_model.gemspec
|
220
|
-
- gemfiles/rails_4.2.gemfile
|
221
214
|
- gemfiles/rails_5.0.gemfile
|
222
215
|
- gemfiles/rails_5.1.gemfile
|
216
|
+
- gemfiles/rails_5.2.gemfile
|
223
217
|
- lib/active_record/connection_adapters/chronomodel_adapter.rb
|
224
218
|
- lib/active_record/tasks/chronomodel_database_tasks.rb
|
225
219
|
- lib/chrono_model.rb
|
@@ -278,7 +272,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
278
272
|
version: '0'
|
279
273
|
requirements: []
|
280
274
|
rubyforge_project:
|
281
|
-
rubygems_version: 2.
|
275
|
+
rubygems_version: 2.7.6.2
|
282
276
|
signing_key:
|
283
277
|
specification_version: 4
|
284
278
|
summary: Temporal extensions (SCD Type II) for Active Record
|