cequel 2.1.0 → 3.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 +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +2 -2
- data/README.md +8 -0
- data/lib/cequel/errors.rb +2 -0
- data/lib/cequel/metal/new_relic_instrumentation.rb +2 -1
- data/lib/cequel/record.rb +8 -0
- data/lib/cequel/record/schema.rb +30 -23
- data/lib/cequel/schema.rb +3 -2
- data/lib/cequel/schema/column.rb +11 -1
- data/lib/cequel/schema/keyspace.rb +18 -7
- data/lib/cequel/schema/patch.rb +152 -0
- data/lib/cequel/schema/table.rb +55 -137
- data/lib/cequel/schema/table_desc_dsl.rb +196 -0
- data/lib/cequel/schema/table_differ.rb +112 -0
- data/lib/cequel/schema/table_property.rb +14 -0
- data/lib/cequel/schema/table_reader.rb +81 -85
- data/lib/cequel/schema/table_updater.rb +0 -17
- data/lib/cequel/schema/table_writer.rb +10 -9
- data/lib/cequel/version.rb +1 -1
- data/spec/examples/metal/data_set_spec.rb +156 -153
- data/spec/examples/metal/keyspace_spec.rb +4 -4
- data/spec/examples/record/associations_spec.rb +6 -0
- data/spec/examples/record/mass_assignment_spec.rb +2 -2
- data/spec/examples/record/properties_spec.rb +1 -0
- data/spec/examples/record/record_set_spec.rb +1 -1
- data/spec/examples/schema/patch_spec.rb +190 -0
- data/spec/examples/schema/table_differ_spec.rb +280 -0
- data/spec/examples/schema/table_reader_spec.rb +379 -354
- data/spec/examples/schema/table_updater_spec.rb +0 -12
- data/spec/examples/spec_helper.rb +5 -5
- data/spec/examples/spec_support/preparation_spec.rb +4 -0
- data/spec/support/helpers.rb +23 -0
- metadata +9 -6
- data/lib/cequel/schema/create_table_dsl.rb +0 -88
- data/lib/cequel/schema/table_synchronizer.rb +0 -180
- data/spec/examples/schema/table_synchronizer_spec.rb +0 -200
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c970b068b50a1215dc4bf58af07dfc5b1b936214
|
4
|
+
data.tar.gz: c7470426d1cac668b2bd698d7f35608835b2bf0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ce7dfd8aa2d73dc6d6748a789b4cd84ab137fb7c3d98bc70df830c6f64d8fb86a0e4e3fb26de6ce0d0c8167db8fcb8a0a2e3c57799f6847cf239db0ae73e4e0
|
7
|
+
data.tar.gz: 886e98099ef58ee431a76f4560e89ad10e3146a0850293671aa8bef45b852fa1bcdab41d2968639ec24dd7bfcba45c516ac88bf1de0f119f3fecf8b15a0eda95
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## 3.0.0
|
2
|
+
* Drop support for changing the type of cluster keys as it is no longer support by Cassandra.
|
3
|
+
* Drop support for non-option based index specification in table schema DSL. For example, `column :author_name, :text, true` must be rewritten as `column :author_name, :text, index: true`.
|
4
|
+
* Fix Relic instrumentation for batch statements [PR 361](https://github.com/cequel/cequel/pull/361)
|
5
|
+
* Don't set table name when it is already present [PR 364](https://github.com/cequel/cequel/pull/364)
|
6
|
+
|
1
7
|
## 2.1.0
|
2
8
|
|
3
9
|
* Add ActiveRecord::Enum like support `column :status, :enum, values: { open: 1, closed: 2 }` ([PR 354](https://github.com/cequel/cequel/pull/354))
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -612,6 +612,14 @@ you require this functionality.
|
|
612
612
|
|
613
613
|
## Breaking API changes
|
614
614
|
|
615
|
+
### 3.0
|
616
|
+
|
617
|
+
* Dropped support for changing the type of cluster keys because the ability has
|
618
|
+
been removed from Cassandra. Calls to `#change_column` must be removed.
|
619
|
+
* Dropped support for previously deprecated signature of the `#column` method
|
620
|
+
of schema DSL. Uses like `column :my_column, :text, true` must be rewritten
|
621
|
+
as `#column :my_column, :text, indexed: true`
|
622
|
+
|
615
623
|
### 2.0
|
616
624
|
|
617
625
|
* dropped support for jruby (Due to difficult to work around bugs in jruby. PRs welcome to restore jruby compatibility.)
|
data/lib/cequel/errors.rb
CHANGED
@@ -16,7 +16,7 @@ module Cequel
|
|
16
16
|
define_method :execute_with_options_with_newrelic do |statement, options|
|
17
17
|
|
18
18
|
operation = nil
|
19
|
-
statement_txt = nil
|
19
|
+
statement_txt = nil
|
20
20
|
statement_words = nil
|
21
21
|
|
22
22
|
if statement.is_a?(::Cequel::Metal::Statement)
|
@@ -25,6 +25,7 @@ module Cequel
|
|
25
25
|
operation = statement_words.first.downcase
|
26
26
|
elsif statement.is_a?(::Cassandra::Statements::Batch)
|
27
27
|
operation = "batch"
|
28
|
+
statement_txt = 'BEGIN BATCH'
|
28
29
|
end
|
29
30
|
|
30
31
|
callback = Proc.new do |result, scoped_metric, elapsed|
|
data/lib/cequel/record.rb
CHANGED
@@ -136,6 +136,14 @@ module Cequel
|
|
136
136
|
weak_descendants << WeakRef.new(base)
|
137
137
|
end
|
138
138
|
|
139
|
+
# This is probably not the method you are looking for.
|
140
|
+
#
|
141
|
+
# Clear descendants list. Useful in tests to ensure bogus record classes
|
142
|
+
# are not synced.
|
143
|
+
def forget_all_descendants!
|
144
|
+
weak_descendants.clear
|
145
|
+
end
|
146
|
+
|
139
147
|
private
|
140
148
|
|
141
149
|
def weak_descendants
|
data/lib/cequel/record/schema.rb
CHANGED
@@ -20,7 +20,7 @@ module Cequel
|
|
20
20
|
|
21
21
|
included do
|
22
22
|
class_attribute :table_name, instance_writer: false
|
23
|
-
self.table_name = name.demodulize.tableize.to_sym unless name.nil?
|
23
|
+
self.table_name = name.demodulize.tableize.to_sym unless name.nil? || self.table_name.present?
|
24
24
|
end
|
25
25
|
|
26
26
|
#
|
@@ -80,21 +80,24 @@ module Cequel
|
|
80
80
|
# @return [void]
|
81
81
|
#
|
82
82
|
def synchronize_schema
|
83
|
-
reader = get_table_reader
|
84
|
-
return if reader.materialized_view?
|
85
|
-
Cequel::Schema::TableSynchronizer
|
86
|
-
.apply(connection, reader.read, table_schema)
|
87
|
-
end
|
88
|
-
|
89
|
-
#
|
90
|
-
# Return a {TableReader} instance
|
91
|
-
#
|
92
|
-
# @return [Schema::TableReader] object
|
93
|
-
#
|
94
|
-
def get_table_reader
|
95
83
|
fail MissingTableNameError unless table_name
|
96
84
|
|
97
|
-
|
85
|
+
patch =
|
86
|
+
begin
|
87
|
+
existing_table_descriptor = Cequel::Schema::TableReader.read(connection,
|
88
|
+
table_name)
|
89
|
+
|
90
|
+
return if existing_table_descriptor.materialized_view?
|
91
|
+
|
92
|
+
Cequel::Schema::TableDiffer.new(existing_table_descriptor,
|
93
|
+
table_schema)
|
94
|
+
.call
|
95
|
+
|
96
|
+
rescue NoSuchTableError
|
97
|
+
Cequel::Schema::TableWriter.new(table_schema)
|
98
|
+
end
|
99
|
+
|
100
|
+
patch.statements.each { |stmt| connection.execute(stmt) }
|
98
101
|
end
|
99
102
|
|
100
103
|
#
|
@@ -113,46 +116,50 @@ module Cequel
|
|
113
116
|
# specified in the class definition
|
114
117
|
#
|
115
118
|
def table_schema
|
116
|
-
|
119
|
+
dsl.table
|
117
120
|
end
|
118
121
|
|
119
122
|
protected
|
120
123
|
|
124
|
+
def dsl
|
125
|
+
@dsl ||= Cequel::Schema::TableDescDsl.new(table_name)
|
126
|
+
end
|
127
|
+
|
121
128
|
def key(name, type, options = {})
|
122
129
|
super
|
123
130
|
if options[:partition]
|
124
|
-
|
131
|
+
dsl.partition_key(name, type)
|
125
132
|
else
|
126
|
-
|
133
|
+
dsl.key(name, type, options[:order])
|
127
134
|
end
|
128
135
|
end
|
129
136
|
|
130
137
|
def column(name, type, options = {})
|
131
138
|
super
|
132
|
-
|
139
|
+
dsl.column(name, type, options)
|
133
140
|
end
|
134
141
|
|
135
142
|
def list(name, type, options = {})
|
136
143
|
super
|
137
|
-
|
144
|
+
dsl.list(name, type)
|
138
145
|
end
|
139
146
|
|
140
147
|
def set(name, type, options = {})
|
141
148
|
super
|
142
|
-
|
149
|
+
dsl.set(name, type)
|
143
150
|
end
|
144
151
|
|
145
152
|
def map(name, key_type, value_type, options = {})
|
146
153
|
super
|
147
|
-
|
154
|
+
dsl.map(name, key_type, value_type)
|
148
155
|
end
|
149
156
|
|
150
157
|
def table_property(name, value)
|
151
|
-
|
158
|
+
dsl.with(name, value)
|
152
159
|
end
|
153
160
|
|
154
161
|
def compact_storage
|
155
|
-
|
162
|
+
dsl.compact_storage
|
156
163
|
end
|
157
164
|
end
|
158
165
|
|
data/lib/cequel/schema.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
require 'cequel/schema/column'
|
3
|
-
require 'cequel/schema/
|
3
|
+
require 'cequel/schema/table_desc_dsl'
|
4
4
|
require 'cequel/schema/keyspace'
|
5
5
|
require 'cequel/schema/migration_validator'
|
6
6
|
require 'cequel/schema/table'
|
7
7
|
require 'cequel/schema/table_property'
|
8
8
|
require 'cequel/schema/table_reader'
|
9
|
-
require 'cequel/schema/
|
9
|
+
require 'cequel/schema/table_differ'
|
10
|
+
require 'cequel/schema/patch'
|
10
11
|
require 'cequel/schema/table_updater'
|
11
12
|
require 'cequel/schema/table_writer'
|
12
13
|
require 'cequel/schema/update_table_dsl'
|
data/lib/cequel/schema/column.rb
CHANGED
@@ -71,6 +71,15 @@ module Cequel
|
|
71
71
|
false
|
72
72
|
end
|
73
73
|
|
74
|
+
# Indicates if this column is indexed. Overridden by subclasses that
|
75
|
+
# support indexing.
|
76
|
+
#
|
77
|
+
# @return [Boolean] true if this column has a secondary index
|
78
|
+
#
|
79
|
+
def indexed?
|
80
|
+
false
|
81
|
+
end
|
82
|
+
|
74
83
|
#
|
75
84
|
# @param type_in [Symbol,Type] type to check against
|
76
85
|
# @return [Boolean] true if this column has the type given by `type_in`
|
@@ -96,7 +105,7 @@ module Cequel
|
|
96
105
|
# @api private
|
97
106
|
#
|
98
107
|
def to_cql
|
99
|
-
"#{@name} #{@type}
|
108
|
+
%Q|"#{@name}" #{@type}|
|
100
109
|
end
|
101
110
|
|
102
111
|
#
|
@@ -107,6 +116,7 @@ module Cequel
|
|
107
116
|
def ==(other)
|
108
117
|
to_cql == other.to_cql
|
109
118
|
end
|
119
|
+
alias_method :eql?, :==
|
110
120
|
|
111
121
|
#
|
112
122
|
# @return [String] the column's name
|
@@ -52,7 +52,7 @@ module Cequel
|
|
52
52
|
}
|
53
53
|
|
54
54
|
options = options.symbolize_keys
|
55
|
-
options.reverse_merge!(keyspace.configuration)
|
55
|
+
options.reverse_merge!(keyspace.configuration.symbolize_keys)
|
56
56
|
options.reverse_merge!(default_options)
|
57
57
|
|
58
58
|
if options.key?(:class)
|
@@ -148,8 +148,7 @@ module Cequel
|
|
148
148
|
# @see CreateTableDSL
|
149
149
|
#
|
150
150
|
def create_table(name, &block)
|
151
|
-
table =
|
152
|
-
CreateTableDSL.apply(table, &block)
|
151
|
+
table = TableDescDsl.new(name).eval(&block)
|
153
152
|
TableWriter.apply(keyspace, table)
|
154
153
|
end
|
155
154
|
|
@@ -224,13 +223,25 @@ module Cequel
|
|
224
223
|
# @see #create_table Example of DSL usage
|
225
224
|
#
|
226
225
|
def sync_table(name, &block)
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
226
|
+
new_table_desc = TableDescDsl.new(name).eval(&block)
|
227
|
+
patch = if has_table?(name)
|
228
|
+
existing_table_desc = read_table(name)
|
229
|
+
TableDiffer.new(existing_table_desc, new_table_desc).call
|
230
|
+
else
|
231
|
+
TableWriter.new(new_table_desc) # close enough to a patch
|
232
|
+
end
|
233
|
+
|
234
|
+
patch.statements.each{|stmt| keyspace.execute(stmt) }
|
231
235
|
end
|
232
236
|
alias_method :synchronize_table, :sync_table
|
233
237
|
|
238
|
+
|
239
|
+
# Returns true iff the specified table name exists in the keyspace.
|
240
|
+
#
|
241
|
+
def has_table?(table_name)
|
242
|
+
!!read_table(table_name)
|
243
|
+
end
|
244
|
+
|
234
245
|
protected
|
235
246
|
|
236
247
|
attr_reader :keyspace
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Cequel
|
3
|
+
module Schema
|
4
|
+
#
|
5
|
+
# The set of changes needed to transform a table from its current form to a
|
6
|
+
# desired form. `Patch`es are immutable.
|
7
|
+
#
|
8
|
+
class Patch
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
protected def initialize(changes)
|
12
|
+
@changes = changes
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :changes
|
16
|
+
|
17
|
+
def_delegator :changes, :empty?
|
18
|
+
|
19
|
+
def statements
|
20
|
+
changes.map(&:to_cql)
|
21
|
+
end
|
22
|
+
|
23
|
+
class AbstractChange
|
24
|
+
protected def initialize(table, *post_init_args)
|
25
|
+
@table = table
|
26
|
+
|
27
|
+
post_init(*post_init_args)
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :table
|
31
|
+
|
32
|
+
def to_cql
|
33
|
+
fail NotImplementedError
|
34
|
+
end
|
35
|
+
|
36
|
+
def inspect
|
37
|
+
"#<#{self.class.name} #{to_cql}>"
|
38
|
+
end
|
39
|
+
|
40
|
+
def ==(other)
|
41
|
+
other.class == self.class &&
|
42
|
+
other.table == self.table &&
|
43
|
+
subclass_eql?(other)
|
44
|
+
end
|
45
|
+
|
46
|
+
def eql?(other)
|
47
|
+
self == other
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def subclass_eql?(other)
|
53
|
+
fail NotImplementedError
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class SetTableProperties < AbstractChange
|
58
|
+
protected def post_init()
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_cql
|
62
|
+
%Q|ALTER TABLE "#{table.name}" WITH #{properties.map(&:to_cql).join(' AND ')}|
|
63
|
+
end
|
64
|
+
|
65
|
+
def properties
|
66
|
+
table.properties.values
|
67
|
+
end
|
68
|
+
|
69
|
+
protected
|
70
|
+
|
71
|
+
def subclass_eql?(other)
|
72
|
+
other.properties == propreties
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class DropIndex < AbstractChange
|
77
|
+
protected def post_init(column_with_obsolete_idx)
|
78
|
+
@index_name = column_with_obsolete_idx.index_name
|
79
|
+
end
|
80
|
+
|
81
|
+
attr_reader :index_name
|
82
|
+
|
83
|
+
def to_cql
|
84
|
+
%Q|DROP INDEX IF EXISTS "#{index_name}"|
|
85
|
+
end
|
86
|
+
|
87
|
+
protected
|
88
|
+
|
89
|
+
def subclass_eql?(other)
|
90
|
+
other.index_name == index_name
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class AddIndex < AbstractChange
|
95
|
+
protected def post_init(column)
|
96
|
+
@column = column
|
97
|
+
@index_name = column.index_name
|
98
|
+
end
|
99
|
+
|
100
|
+
attr_reader :column, :index_name
|
101
|
+
|
102
|
+
def to_cql
|
103
|
+
%Q|CREATE INDEX "#{index_name}" ON "#{table.name}" ("#{column.name}")|
|
104
|
+
end
|
105
|
+
|
106
|
+
protected
|
107
|
+
|
108
|
+
def subclass_eql?(other)
|
109
|
+
other.column == column &&
|
110
|
+
other.index_name == index_name
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class AddColumn < AbstractChange
|
115
|
+
protected def post_init(column)
|
116
|
+
@column = column
|
117
|
+
end
|
118
|
+
|
119
|
+
attr_reader :column
|
120
|
+
|
121
|
+
def to_cql
|
122
|
+
%Q|ALTER TABLE "#{table.name}" ADD #{column.to_cql}|
|
123
|
+
end
|
124
|
+
|
125
|
+
protected
|
126
|
+
|
127
|
+
def subclass_eql?(other)
|
128
|
+
other.column == column
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
class RenameColumn < AbstractChange
|
133
|
+
protected def post_init(old_column, new_column)
|
134
|
+
@old_name, @new_name = old_column.name, new_column.name
|
135
|
+
end
|
136
|
+
|
137
|
+
attr_reader :old_name, :new_name
|
138
|
+
|
139
|
+
def to_cql
|
140
|
+
%Q|ALTER TABLE "#{table.name}" RENAME "#{old_name}" TO "#{new_name}"|
|
141
|
+
end
|
142
|
+
|
143
|
+
protected
|
144
|
+
|
145
|
+
def subclass_eql?(other)
|
146
|
+
other.old_name == old_name &&
|
147
|
+
other.new_name == new_name
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|