db_schema 0.2.5 → 0.3.rc1

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.
@@ -1,29 +1,48 @@
1
+ require 'dry/equalizer'
2
+
1
3
  module DbSchema
2
4
  class Configuration
3
- attr_reader :adapter, :host, :port, :database, :user, :password
4
-
5
- def initialize(adapter: 'postgres', host: 'localhost', port: 5432, database:, user: nil, password: '', log_changes: true, dry_run: false, post_check: true)
6
- @adapter = adapter
7
- @host = host
8
- @port = port
9
- @database = database
10
- @user = user
11
- @password = password
12
- @log_changes = log_changes
13
- @dry_run = dry_run
14
- @post_check = post_check
5
+ include Dry::Equalizer(:params)
6
+
7
+ DEFAULT_VALUES = {
8
+ adapter: 'postgres',
9
+ host: 'localhost',
10
+ port: 5432,
11
+ database: nil,
12
+ user: nil,
13
+ password: '',
14
+ log_changes: true,
15
+ dry_run: false,
16
+ post_check: true
17
+ }.freeze
18
+
19
+ def initialize(params = {})
20
+ @params = DEFAULT_VALUES.merge(params)
21
+ end
22
+
23
+ def merge(new_params)
24
+ Configuration.new(@params.merge(new_params))
25
+ end
26
+
27
+ [:adapter, :host, :port, :database, :user, :password].each do |param_name|
28
+ define_method(param_name) do
29
+ @params[param_name]
30
+ end
15
31
  end
16
32
 
17
33
  def log_changes?
18
- @log_changes
34
+ @params[:log_changes]
19
35
  end
20
36
 
21
37
  def dry_run?
22
- @dry_run
38
+ @params[:dry_run]
23
39
  end
24
40
 
25
41
  def post_check_enabled?
26
- @post_check
42
+ @params[:post_check]
27
43
  end
44
+
45
+ protected
46
+ attr_reader :params
28
47
  end
29
48
  end
@@ -1,255 +1,10 @@
1
1
  require 'dry/equalizer'
2
2
 
3
- module DbSchema
4
- module Definitions
5
- class Schema
6
- include Dry::Equalizer(:tables, :enums, :extensions)
7
- attr_reader :tables, :enums, :extensions
8
- attr_writer :tables
9
-
10
- def initialize(tables: [], enums: [], extensions: [])
11
- @tables = tables
12
- @enums = enums
13
- @extensions = extensions
14
- end
15
-
16
- def [](table_name)
17
- tables.find { |table| table.name == table_name } || NullTable.new
18
- end
19
- end
20
-
21
- class Table
22
- include Dry::Equalizer(:name, :fields, :indices, :checks, :foreign_keys)
23
- attr_reader :name, :fields, :indices, :checks, :foreign_keys
24
-
25
- def initialize(name, fields: [], indices: [], checks: [], foreign_keys: [])
26
- @name = name.to_sym
27
- @fields = fields
28
- @indices = indices
29
- @checks = checks
30
- @foreign_keys = foreign_keys
31
- end
32
-
33
- def has_expressions?
34
- fields.any?(&:default_is_expression?) ||
35
- indices.any?(&:has_expressions?) ||
36
- checks.any?
37
- end
38
-
39
- def [](field_name)
40
- fields.find { |field| field.name == field_name }
41
- end
42
-
43
- def with_name(new_name)
44
- Table.new(
45
- new_name,
46
- fields: fields,
47
- indices: indices,
48
- checks: checks,
49
- foreign_keys: foreign_keys
50
- )
51
- end
52
-
53
- def with_fields(new_fields)
54
- Table.new(
55
- name,
56
- fields: new_fields,
57
- indices: indices,
58
- checks: checks,
59
- foreign_keys: foreign_keys
60
- )
61
- end
62
-
63
- def with_indices(new_indices)
64
- Table.new(
65
- name,
66
- fields: fields,
67
- indices: new_indices,
68
- checks: checks,
69
- foreign_keys: foreign_keys
70
- )
71
- end
72
-
73
- def with_foreign_keys(new_foreign_keys)
74
- Table.new(
75
- name,
76
- fields: fields,
77
- indices: indices,
78
- checks: checks,
79
- foreign_keys: new_foreign_keys
80
- )
81
- end
82
- end
83
-
84
- class NullTable < Table
85
- def initialize; end
86
- end
87
-
88
- class Index
89
- include Dry::Equalizer(:name, :columns, :unique?, :type, :condition)
90
- attr_reader :name, :columns, :type, :condition
91
-
92
- def initialize(name:, columns:, unique: false, type: :btree, condition: nil)
93
- @name = name.to_sym
94
- @columns = columns
95
- @unique = unique
96
- @type = type
97
- @condition = condition
98
- end
99
-
100
- def unique?
101
- @unique
102
- end
103
-
104
- def btree?
105
- type == :btree
106
- end
107
-
108
- def columns_to_sequel
109
- if btree?
110
- columns.map(&:ordered_expression)
111
- else
112
- columns.map(&:to_sequel)
113
- end
114
- end
115
-
116
- def has_expressions?
117
- !condition.nil? || columns.any?(&:expression?)
118
- end
119
-
120
- def with_name(new_name)
121
- Index.new(
122
- name: new_name,
123
- columns: columns,
124
- unique: unique?,
125
- type: type,
126
- condition: condition
127
- )
128
- end
129
-
130
- class Column
131
- include Dry::Equalizer(:name, :order, :nulls)
132
- attr_reader :name, :order, :nulls
133
-
134
- def initialize(name, order: :asc, nulls: order == :asc ? :last : :first)
135
- @name = name
136
- @order = order
137
- @nulls = nulls
138
- end
139
-
140
- def asc?
141
- @order == :asc
142
- end
143
-
144
- def desc?
145
- @order == :desc
146
- end
147
-
148
- def ordered_expression
149
- if asc?
150
- Sequel.asc(to_sequel, nulls: nulls)
151
- else
152
- Sequel.desc(to_sequel, nulls: nulls)
153
- end
154
- end
155
- end
156
-
157
- class TableField < Column
158
- def expression?
159
- false
160
- end
161
-
162
- def index_name_segment
163
- name
164
- end
165
-
166
- def to_sequel
167
- name
168
- end
169
- end
170
-
171
- class Expression < Column
172
- def expression?
173
- true
174
- end
175
-
176
- def index_name_segment
177
- name.scan(/\b[A-Za-z0-9_]+\b/).join('_')
178
- end
179
-
180
- def to_sequel
181
- Sequel.lit("(#{name})")
182
- end
183
- end
184
- end
185
-
186
- class ForeignKey
187
- include Dry::Equalizer(:name, :fields, :table, :keys, :on_update, :on_delete, :deferrable?)
188
- attr_reader :name, :fields, :table, :keys, :on_update, :on_delete
189
-
190
- def initialize(name:, fields:, table:, keys: [], on_update: :no_action, on_delete: :no_action, deferrable: false)
191
- @name = name
192
- @fields = fields
193
- @table = table
194
- @keys = keys
195
- @on_update = on_update
196
- @on_delete = on_delete
197
- @deferrable = deferrable
198
- end
199
-
200
- def references_primary_key?
201
- keys.empty?
202
- end
203
-
204
- def deferrable?
205
- @deferrable
206
- end
207
-
208
- def options
209
- {
210
- deferrable: deferrable?,
211
- name: name,
212
- on_delete: on_delete,
213
- on_update: on_update
214
- }.tap do |options|
215
- options[:key] = keys unless references_primary_key?
216
- end
217
- end
218
- end
219
-
220
- class CheckConstraint
221
- include Dry::Equalizer(:name, :condition)
222
- attr_reader :name, :condition
223
-
224
- def initialize(name:, condition:)
225
- @name = name.to_sym
226
- @condition = condition
227
- end
228
- end
229
-
230
- class Enum
231
- include Dry::Equalizer(:name, :values)
232
- attr_reader :name, :values
233
-
234
- def initialize(name, values)
235
- @name = name
236
- @values = values
237
- end
238
-
239
- def with_name(new_name)
240
- Enum.new(new_name, values)
241
- end
242
- end
243
-
244
- class Extension
245
- include Dry::Equalizer(:name)
246
- attr_reader :name
247
-
248
- def initialize(name)
249
- @name = name
250
- end
251
- end
252
- end
253
- end
254
-
3
+ require_relative 'definitions/schema'
4
+ require_relative 'definitions/table'
255
5
  require_relative 'definitions/field'
6
+ require_relative 'definitions/index'
7
+ require_relative 'definitions/foreign_key'
8
+ require_relative 'definitions/check_constraint'
9
+ require_relative 'definitions/enum'
10
+ require_relative 'definitions/extension'
@@ -0,0 +1,17 @@
1
+ module DbSchema
2
+ module Definitions
3
+ class CheckConstraint
4
+ include Dry::Equalizer(:name, :condition)
5
+ attr_reader :name, :condition
6
+
7
+ def initialize(name:, condition:)
8
+ @name = name.to_sym
9
+ @condition = condition
10
+ end
11
+ end
12
+
13
+ class NullCheckConstraint < CheckConstraint
14
+ def initialize; end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module DbSchema
2
+ module Definitions
3
+ class Enum
4
+ include Dry::Equalizer(:name, :values)
5
+ attr_reader :name, :values
6
+
7
+ def initialize(name, values)
8
+ @name = name
9
+ @values = values
10
+ end
11
+
12
+ def with_name(new_name)
13
+ Enum.new(new_name, values)
14
+ end
15
+ end
16
+
17
+ class NullEnum < Enum
18
+ def initialize; end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,12 @@
1
+ module DbSchema
2
+ module Definitions
3
+ class Extension
4
+ include Dry::Equalizer(:name)
5
+ attr_reader :name
6
+
7
+ def initialize(name)
8
+ @name = name
9
+ end
10
+ end
11
+ end
12
+ end
@@ -94,5 +94,11 @@ module DbSchema
94
94
  end
95
95
  end
96
96
  end
97
+
98
+ class NullField < Field::Base
99
+ def initialize
100
+ super(nil)
101
+ end
102
+ end
97
103
  end
98
104
  end
@@ -0,0 +1,41 @@
1
+ module DbSchema
2
+ module Definitions
3
+ class ForeignKey
4
+ include Dry::Equalizer(:name, :fields, :table, :keys, :on_update, :on_delete, :deferrable?)
5
+ attr_reader :name, :fields, :table, :keys, :on_update, :on_delete
6
+
7
+ def initialize(name:, fields:, table:, keys: [], on_update: :no_action, on_delete: :no_action, deferrable: false)
8
+ @name = name
9
+ @fields = fields
10
+ @table = table
11
+ @keys = keys
12
+ @on_update = on_update
13
+ @on_delete = on_delete
14
+ @deferrable = deferrable
15
+ end
16
+
17
+ def references_primary_key?
18
+ keys.empty?
19
+ end
20
+
21
+ def deferrable?
22
+ @deferrable
23
+ end
24
+
25
+ def options
26
+ {
27
+ deferrable: deferrable?,
28
+ name: name,
29
+ on_delete: on_delete,
30
+ on_update: on_update
31
+ }.tap do |options|
32
+ options[:key] = keys unless references_primary_key?
33
+ end
34
+ end
35
+ end
36
+
37
+ class NullForeignKey < ForeignKey
38
+ def initialize; end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,56 @@
1
+ module DbSchema
2
+ module Definitions
3
+ class Index
4
+ include Dry::Equalizer(:name, :columns, :unique?, :type, :condition)
5
+ attr_reader :name, :columns, :type, :condition
6
+
7
+ def initialize(name:, columns:, unique: false, type: :btree, condition: nil)
8
+ @name = name.to_sym
9
+ @columns = columns
10
+ @unique = unique
11
+ @type = type
12
+ @condition = condition
13
+ end
14
+
15
+ def unique?
16
+ @unique
17
+ end
18
+
19
+ def btree?
20
+ type == :btree
21
+ end
22
+
23
+ def columns_to_sequel
24
+ if btree?
25
+ columns.map(&:ordered_expression)
26
+ else
27
+ columns.map(&:to_sequel)
28
+ end
29
+ end
30
+
31
+ def has_expressions?
32
+ !condition.nil? || columns.any?(&:expression?)
33
+ end
34
+
35
+ def with_name(new_name)
36
+ Index.new(
37
+ name: new_name,
38
+ columns: columns,
39
+ unique: unique?,
40
+ type: type,
41
+ condition: condition
42
+ )
43
+ end
44
+ end
45
+
46
+ class NullIndex < Index
47
+ def initialize
48
+ @columns = []
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ require_relative 'index/column'
55
+ require_relative 'index/table_field'
56
+ require_relative 'index/expression'