schema_plus_pg_indexes 0.1.6 → 0.1.7
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/README.md +1 -0
- data/lib/schema_plus_pg_indexes/middleware/postgresql/dumper.rb +7 -10
- data/lib/schema_plus_pg_indexes/middleware/postgresql/schema.rb +2 -2
- data/lib/schema_plus_pg_indexes/middleware/postgresql/sql.rb +5 -3
- data/lib/schema_plus_pg_indexes/version.rb +1 -1
- data/spec/index_definition_spec.rb +31 -12
- data/spec/index_spec.rb +37 -4
- data/spec/schema_dumper_spec.rb +12 -11
- data/spec/spec_helper.rb +9 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 23c0466d72bdac73b797047b1b0db33bbb840672
|
4
|
+
data.tar.gz: 51c899f934b0d2b480d63e2759b4b9d148b3351d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e1690a53c5d96bbdfa7f5a33a12db3a91f72c59c3907bee9908f1556bc83eaaa2c629080ac5ed5c9ee57989094fb27d63e43b40b70574b88e65bc13cc4ea1ce1
|
7
|
+
data.tar.gz: b5fc2d3442f501ec154f79f8f2a0d018ca667ea11e266df1232fe2a45be825d3989234c540f31a60366009aaaf20c8e3fdda96f0bfb0a967bdf1bdeba64cc743
|
data/README.md
CHANGED
@@ -61,6 +61,7 @@ schema_plus_pg_indexes is tested on
|
|
61
61
|
|
62
62
|
## History
|
63
63
|
|
64
|
+
* v0.1.7 - Bug fix: mix of columns & expressions (#5)
|
64
65
|
* v0.1.6 - Bug fix: operator class & multiple columns (#4). Thanks to [@nbudin](https://github.com/nbudin)
|
65
66
|
* v0.1.5 - Bug fix: `t.index` without column in `change_table`
|
66
67
|
* v0.1.1 through v0.1.4 - Conform to schema_dev updates
|
@@ -11,16 +11,13 @@ module SchemaPlusPgIndexes
|
|
11
11
|
|
12
12
|
env.table.indexes.each do |index_dump|
|
13
13
|
index_def = index_defs.find(&its.name == index_dump.name)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
else
|
22
|
-
index_dump.add_option "operator_class: {" + index_def.operator_classes.map{|column, val| "#{column.inspect}=>#{val.inspect}"}.join(", ") + "}"
|
23
|
-
end
|
14
|
+
index_dump.add_option "case_sensitive: false" unless index_def.case_sensitive?
|
15
|
+
index_dump.add_option "expression: #{index_def.expression.inspect}" if index_def.expression and index_def.case_sensitive?
|
16
|
+
unless index_def.operator_classes.blank?
|
17
|
+
if index_def.columns.uniq.length == 1 && index_def.operator_classes.values.uniq.length == 1
|
18
|
+
index_dump.add_option "operator_class: #{index_def.operator_classes.values.first.inspect}"
|
19
|
+
else
|
20
|
+
index_dump.add_option "operator_class: {" + index_def.operator_classes.map{|column, val| "#{column.inspect}=>#{val.inspect}"}.join(", ") + "}"
|
24
21
|
end
|
25
22
|
end
|
26
23
|
end
|
@@ -76,13 +76,13 @@ module SchemaPlusPgIndexes
|
|
76
76
|
# only applies to character, character varying, and text
|
77
77
|
if expression
|
78
78
|
rexp_lower = %r{\blower\(\(?([^)]+)(\)::text)?\)}
|
79
|
-
if expression.match /\A#{rexp_lower}(?:, #{rexp_lower})*\z/
|
79
|
+
if expression.match /\A#{rexp_lower}(?:, #{rexp_lower})*\z/i
|
80
80
|
case_insensitive_columns = expression.scan(rexp_lower).map(&:first).select{|column| %W[char varchar text].include? types[column]}
|
81
81
|
if case_insensitive_columns.any?
|
82
82
|
case_sensitive = false
|
83
83
|
column_names = index_keys.map { |index_key|
|
84
84
|
index_key == '0' ? case_insensitive_columns.shift : columns[index_key]
|
85
|
-
}.compact
|
85
|
+
}.compact | column_names
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
@@ -52,9 +52,7 @@ module SchemaPlusPgIndexes
|
|
52
52
|
operator_classes = Hash[column_names.map {|name| [name, operator_classes]}]
|
53
53
|
end
|
54
54
|
|
55
|
-
if
|
56
|
-
env.sql.columns = expression
|
57
|
-
elsif operator_classes or case_insensitive
|
55
|
+
if operator_classes or case_insensitive
|
58
56
|
option_strings = Hash[column_names.map {|name| [name, '']}]
|
59
57
|
(operator_classes||{}).stringify_keys.each do |column, opclass|
|
60
58
|
option_strings[column] += " #{opclass}" if opclass
|
@@ -72,6 +70,10 @@ module SchemaPlusPgIndexes
|
|
72
70
|
|
73
71
|
env.sql.columns = quoted_column_names.join(', ')
|
74
72
|
end
|
73
|
+
|
74
|
+
if expression
|
75
|
+
env.sql.columns = (env.sql.columns.split(/ *, */).reject{|col| expression =~ %r{\b#{col.gsub(/['"]/, '')}\b} } + [expression]).join(', ')
|
76
|
+
end
|
75
77
|
end
|
76
78
|
end
|
77
79
|
end
|
@@ -5,7 +5,7 @@ describe "Index definition" do
|
|
5
5
|
|
6
6
|
let(:migration) { ::ActiveRecord::Migration }
|
7
7
|
|
8
|
-
before(:
|
8
|
+
before(:each) do
|
9
9
|
define_schema do
|
10
10
|
create_table :users, :force => true do |t|
|
11
11
|
t.string :login
|
@@ -23,16 +23,6 @@ describe "Index definition" do
|
|
23
23
|
class Post < ::ActiveRecord::Base ; end
|
24
24
|
end
|
25
25
|
|
26
|
-
around(:each) do |example|
|
27
|
-
migration.suppress_messages do
|
28
|
-
example.run
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
after(:each) do
|
33
|
-
migration.remove_index :users, :name => 'users_login_index' if migration.index_name_exists? :users, 'users_login_index', true
|
34
|
-
end
|
35
|
-
|
36
26
|
context "when case insensitive is added" do
|
37
27
|
|
38
28
|
before(:each) do
|
@@ -60,7 +50,7 @@ describe "Index definition" do
|
|
60
50
|
end
|
61
51
|
|
62
52
|
|
63
|
-
context "when index contains expression" do
|
53
|
+
context "when index contains an expression" do
|
64
54
|
before(:each) do
|
65
55
|
migration.execute "CREATE INDEX users_login_index ON users (extract(EPOCH from deleted_at)) WHERE deleted_at IS NULL"
|
66
56
|
User.reset_column_information
|
@@ -89,6 +79,35 @@ describe "Index definition" do
|
|
89
79
|
|
90
80
|
end
|
91
81
|
|
82
|
+
context "when index contains mix of expressions and columns" do
|
83
|
+
before(:each) do
|
84
|
+
define_schema do
|
85
|
+
create_table :users, :force => true do |t|
|
86
|
+
t.string :alpha
|
87
|
+
t.string :beta
|
88
|
+
t.string :gamma
|
89
|
+
t.string :delta
|
90
|
+
end
|
91
|
+
execute "CREATE INDEX multi ON users (alpha, (upper(beta)), gamma, (upper(delta)))"
|
92
|
+
end
|
93
|
+
User.reset_column_information
|
94
|
+
@index = User.indexes.detect { |i| i.expression.present? }
|
95
|
+
end
|
96
|
+
|
97
|
+
it "exists" do
|
98
|
+
expect(@index).not_to be_nil
|
99
|
+
end
|
100
|
+
|
101
|
+
it "havs columns defined" do
|
102
|
+
expect(@index.columns).to eq(["alpha", "gamma"])
|
103
|
+
end
|
104
|
+
|
105
|
+
it "defines expression" do
|
106
|
+
expect(@index.expression).to eq("upper((beta)::text), upper((delta)::text)")
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
92
111
|
context "when index has a non-btree type" do
|
93
112
|
before(:each) do
|
94
113
|
migration.execute "CREATE INDEX users_login_index ON users USING hash(login)"
|
data/spec/index_spec.rb
CHANGED
@@ -21,10 +21,8 @@ describe "index" do
|
|
21
21
|
context "extra features" do
|
22
22
|
|
23
23
|
before(:each) do
|
24
|
-
connection.tables.each do |table| connection.drop_table table, cascade: true end
|
25
|
-
|
26
24
|
define_schema do
|
27
|
-
create_table :users
|
25
|
+
create_table :users do |t|
|
28
26
|
t.string :login
|
29
27
|
t.text :address
|
30
28
|
t.jsonb :json_col
|
@@ -88,7 +86,7 @@ describe "index" do
|
|
88
86
|
context "create table" do
|
89
87
|
it "defines index with expression only" do
|
90
88
|
define_schema do
|
91
|
-
create_table :users
|
89
|
+
create_table :users do |t|
|
92
90
|
t.string :login
|
93
91
|
t.index :expression => "upper(login)", name: "no_column"
|
94
92
|
end
|
@@ -96,6 +94,41 @@ describe "index" do
|
|
96
94
|
expect(User.indexes.first.expression).to eq("upper((login)::text)")
|
97
95
|
expect(User.indexes.first.name).to eq("no_column")
|
98
96
|
end
|
97
|
+
|
98
|
+
it "defines index with expression as column option" do
|
99
|
+
define_schema do
|
100
|
+
create_table :users do |t|
|
101
|
+
t.string :login, index: { expression: "upper(login)" }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
expect(User.indexes.first.expression).to eq("upper((login)::text)")
|
105
|
+
expect(User.indexes.first.name).to eq("index_users_on_login")
|
106
|
+
expect(User.indexes.first.columns).to be_empty
|
107
|
+
end
|
108
|
+
|
109
|
+
it "defines multi-column index with expression as column option" do
|
110
|
+
define_schema do
|
111
|
+
create_table :users do |t|
|
112
|
+
t.string :name
|
113
|
+
t.string :login, index: { with: "name", expression: "upper(login)" }
|
114
|
+
end
|
115
|
+
end
|
116
|
+
expect(User.indexes.first.expression).to eq("upper((login)::text)")
|
117
|
+
expect(User.indexes.first.name).to eq("index_users_on_login_and_name")
|
118
|
+
expect(User.indexes.first.columns).to eq(["name"])
|
119
|
+
end
|
120
|
+
|
121
|
+
it "defines multi-column index with column option expression that doesn't reference column" do
|
122
|
+
define_schema do
|
123
|
+
create_table :users do |t|
|
124
|
+
t.string :name
|
125
|
+
t.string :login, index: { expression: "upper(name)" }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
expect(User.indexes.first.expression).to eq("upper((name)::text)")
|
129
|
+
expect(User.indexes.first.name).to eq("index_users_on_login")
|
130
|
+
expect(User.indexes.first.columns).to eq(["login"])
|
131
|
+
end
|
99
132
|
end
|
100
133
|
|
101
134
|
context "change table" do
|
data/spec/schema_dumper_spec.rb
CHANGED
@@ -3,18 +3,18 @@ require 'stringio'
|
|
3
3
|
|
4
4
|
describe "Schema dump" do
|
5
5
|
|
6
|
-
before(:
|
6
|
+
before(:each) do
|
7
7
|
ActiveRecord::Migration.suppress_messages do
|
8
8
|
ActiveRecord::Schema.define do
|
9
9
|
connection.tables.each do |table| drop_table table, force: :cascade end
|
10
10
|
|
11
|
-
create_table :users
|
11
|
+
create_table :users do |t|
|
12
12
|
t.string :login
|
13
13
|
t.datetime :deleted_at
|
14
14
|
t.integer :first_post_id
|
15
15
|
end
|
16
16
|
|
17
|
-
create_table :posts
|
17
|
+
create_table :posts do |t|
|
18
18
|
t.text :body
|
19
19
|
t.integer :user_id
|
20
20
|
t.integer :first_comment_id
|
@@ -32,7 +32,7 @@ describe "Schema dump" do
|
|
32
32
|
t.boolean :boolean_col
|
33
33
|
end
|
34
34
|
|
35
|
-
create_table :comments
|
35
|
+
create_table :comments do |t|
|
36
36
|
t.text :body
|
37
37
|
t.integer :post_id
|
38
38
|
t.integer :commenter_id
|
@@ -86,6 +86,13 @@ describe "Schema dump" do
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
+
it "should define multi-column with expression" do
|
90
|
+
with_index Post, :body, :expression => "(least(id, user_id))" do
|
91
|
+
expect(dump_posts).to match(/body.*index.*expression: "LEAST\(id, user_id\)"/)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
|
89
96
|
it "should define operator_class" do
|
90
97
|
with_index Post, :body, :operator_class => 'text_pattern_ops' do
|
91
98
|
expect(dump_posts).to match(/body.*index:.*operator_class: "text_pattern_ops"/)
|
@@ -139,13 +146,7 @@ describe "Schema dump" do
|
|
139
146
|
ActiveRecord::Migration.add_index(model.table_name, columns, options)
|
140
147
|
end
|
141
148
|
model.reset_column_information
|
142
|
-
|
143
|
-
yield
|
144
|
-
ensure
|
145
|
-
ActiveRecord::Migration.suppress_messages do
|
146
|
-
ActiveRecord::Migration.remove_index(model.table_name, :name => determine_index_name(model, columns, options))
|
147
|
-
end
|
148
|
-
end
|
149
|
+
yield
|
149
150
|
end
|
150
151
|
|
151
152
|
def determine_index_name(model, columns, options)
|
data/spec/spec_helper.rb
CHANGED
@@ -17,16 +17,19 @@ Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
|
|
17
17
|
RSpec.configure do |config|
|
18
18
|
config.include(SchemaPlusPgIndexesMatchers)
|
19
19
|
config.warnings = true
|
20
|
+
config.around(:each) do |example|
|
21
|
+
ActiveRecord::Migration.suppress_messages do
|
22
|
+
example.run
|
23
|
+
end
|
24
|
+
end
|
20
25
|
end
|
21
26
|
|
22
27
|
def define_schema(&block)
|
23
|
-
ActiveRecord::
|
24
|
-
|
25
|
-
|
26
|
-
drop_table table, force: :cascade
|
27
|
-
end
|
28
|
-
instance_eval &block
|
28
|
+
ActiveRecord::Schema.define do
|
29
|
+
connection.tables.each do |table|
|
30
|
+
drop_table table, force: :cascade
|
29
31
|
end
|
32
|
+
instance_eval &block
|
30
33
|
end
|
31
34
|
end
|
32
35
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: schema_plus_pg_indexes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ronen barzel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|