schema_plus_pg_indexes 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 809e25804e94035df8d24a57d5a255c8d64c8eb8
4
- data.tar.gz: 92e7716fb86ece5c7f420b22ce6a75cfd36f3677
3
+ metadata.gz: 23c0466d72bdac73b797047b1b0db33bbb840672
4
+ data.tar.gz: 51c899f934b0d2b480d63e2759b4b9d148b3351d
5
5
  SHA512:
6
- metadata.gz: ef0acdf61aeda8a0c6980dba96ccbdb4357f7719476238742700cae71d83d757230b44bf19c353cc468a4ea1e479b1d4b1814e4b75911fcd3876b126af6b331f
7
- data.tar.gz: 2bd3c3b3fb713678d041633c833c7c791e3a9d6909c2b714ce9197105471c38da4dbfcd00c38c90a9c014848a6f21dda7c61d92a05906bf12e16554fa9e9874b
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
- if index_def.columns.blank?
15
- index_dump.add_option "expression: #{index_def.expression.inspect}" if index_def.expression and index_def.columns.blank?
16
- else
17
- index_dump.add_option "case_sensitive: false" unless index_def.case_sensitive?
18
- unless index_def.operator_classes.blank?
19
- if index_def.columns.uniq.length == 1 && index_def.operator_classes.values.uniq.length == 1
20
- index_dump.add_option "operator_class: #{index_def.operator_classes.values.first.inspect}"
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 expression
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
@@ -1,3 +1,3 @@
1
1
  module SchemaPlusPgIndexes
2
- VERSION = "0.1.6"
2
+ VERSION = "0.1.7"
3
3
  end
@@ -5,7 +5,7 @@ describe "Index definition" do
5
5
 
6
6
  let(:migration) { ::ActiveRecord::Migration }
7
7
 
8
- before(:all) do
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)"
@@ -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, :force => true do |t|
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, :force => true do |t|
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
@@ -3,18 +3,18 @@ require 'stringio'
3
3
 
4
4
  describe "Schema dump" do
5
5
 
6
- before(:all) do
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, :force => true do |t|
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, :force => true do |t|
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, :force => true do |t|
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
- begin
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)
@@ -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::Migration.suppress_messages do
24
- ActiveRecord::Schema.define do
25
- connection.tables.each do |table|
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.6
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-09-30 00:00:00.000000000 Z
11
+ date: 2015-10-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord