dymos 0.1.4 → 0.2.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +71 -2
  3. data/lib/dymos/client.rb +16 -0
  4. data/lib/dymos/config.rb +34 -0
  5. data/lib/dymos/model.rb +109 -26
  6. data/lib/dymos/persistence.rb +75 -16
  7. data/lib/dymos/query/base.rb +23 -0
  8. data/lib/dymos/query/create_table.rb +72 -0
  9. data/lib/dymos/query/delete_item.rb +60 -32
  10. data/lib/dymos/query/describe.rb +3 -5
  11. data/lib/dymos/query/get_item.rb +30 -9
  12. data/lib/dymos/query/put_item.rb +67 -41
  13. data/lib/dymos/query/query.rb +112 -26
  14. data/lib/dymos/query/scan.rb +85 -12
  15. data/lib/dymos/query/update_item.rb +97 -50
  16. data/lib/dymos/version.rb +1 -1
  17. data/lib/dymos.rb +6 -4
  18. data/spec/lib/dymos/client_spec.rb +4 -0
  19. data/spec/lib/dymos/config_spec.rb +11 -0
  20. data/spec/lib/dymos/data.yml +154 -0
  21. data/spec/lib/dymos/model_spec.rb +23 -29
  22. data/spec/lib/dymos/query/create_table_spec.rb +56 -0
  23. data/spec/lib/dymos/query/delete_item_spec.rb +22 -79
  24. data/spec/lib/dymos/query/describe_spec.rb +6 -40
  25. data/spec/lib/dymos/query/get_item_spec.rb +8 -47
  26. data/spec/lib/dymos/query/put_item_spec.rb +45 -301
  27. data/spec/lib/dymos/query/query_spec.rb +45 -95
  28. data/spec/lib/dymos/query/scan_spec.rb +49 -43
  29. data/spec/lib/dymos/query/update_item_spec.rb +36 -113
  30. data/spec/lib/dymos/query_spec.rb +150 -0
  31. data/spec/spec_helper.rb +33 -0
  32. metadata +16 -12
  33. data/lib/dymos/command.rb +0 -36
  34. data/lib/dymos/query/attribute.rb +0 -14
  35. data/lib/dymos/query/builder.rb +0 -79
  36. data/lib/dymos/query/expect.rb +0 -65
  37. data/spec/lib/dymos/query/attribute_spec.rb +0 -15
  38. data/spec/lib/dymos/query/builder_spec.rb +0 -23
  39. data/spec/lib/dymos/query/expect_spec.rb +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4f5e6582dcf6a0992c22f3d13d6fcb87fec0bd0f
4
- data.tar.gz: bc4a0800891429d8a80eeeeb08c2250f594c3709
3
+ metadata.gz: a14520d556c3eb1c8f019feca759dc4a8c0bf530
4
+ data.tar.gz: b3d32561a640e4c08611a6df6aa62afe6e7e3f8f
5
5
  SHA512:
6
- metadata.gz: 1053e6b53a07c7cd72357860c883e46b5d38151fb3fe0f0cca29391a36501814b21359442c21d20c64b0b1c875b37a3983020cc3cd705758104e2513883e32ce
7
- data.tar.gz: 1204f174b48bc4a007bfa973738f5e4c06d03e7eab8e6a03e3c38dfefbd05935669ae833ee49c4407ab307e477d3a355aa947c47f8ca924c003d8d20fc04d8e7
6
+ metadata.gz: 3715cc421b3f4453ecfd1e88b1bcb544faf74bf522498bcf77a8f53b2b1119b3563cad5d508a228497ffa2c13d1a0b78f2006783fa6b18de8fd1238fc8403bf6
7
+ data.tar.gz: 1a5ffcbe966d215d3c40605068414ded37b5a692d094ad99d71c9d01c12432f602df60029e59c09c9b13787c53ca4352742db6ebb6358b438893ab56ce3a1664
data/README.md CHANGED
@@ -18,11 +18,80 @@ install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
- TODO: Write usage instructions here
21
+
22
+ ### テーブル生成
23
+
24
+ ```ruby
25
+ Dymos::Query::CreateTable.name('ProductCatalogs')
26
+ .attributes(category: 'S', title: 'S', ISBN:'S', price:'N')
27
+ .keys(category: 'HASH', title: 'RANGE')
28
+ .gsi([{name: 'global_index_isbn', keys: {ISBN: 'HASH'}, projection: {type: 'INCLUDE', attributes: [:title, :ISBN]}, throughput: {read: 20, write: 10}}])
29
+ .lsi([{name: 'local_index_category_price', keys: {category: 'HASH', price: 'RANGE'}}])
30
+ .throughput(read: 20, write: 10)
31
+ ```
32
+
33
+ ### モデル定義
34
+
35
+ ```ruby
36
+ class Product < Dymos::Model
37
+ table 'ProductCatalogs'
38
+ field :category, :integer
39
+ field :title, :string
40
+ field :ISBN, :string
41
+ field :price, :integer
42
+ field :authors, :array
43
+ field :created_at, :time
44
+ end
45
+ ```
46
+
47
+ ### クエリ
48
+ #### 取得
49
+
50
+ ```ruby
51
+ Product.all
52
+ ```
53
+
54
+ ```ruby
55
+ Product.find('Novels', 'The Catcher in the Rye') #key is category && title
56
+ ```
57
+
58
+ ```ruby
59
+ Product.where(category:'Comics').all
60
+ Product.where(category:'Comics').add_filter(:authors,:contains,'John Smith').all
61
+ Product.where(category:'Comics').desc.one
62
+ Product.index(:local_index_category_price).add_condition(:category,'Comics')add_condition(:price,:gt,10000).all
63
+ ```
64
+
65
+ #### 保存
66
+
67
+ ##### 新規
68
+ ```ruby
69
+ product = Product.new(params)
70
+ product.save!
71
+ ```
72
+
73
+ ##### 更新
74
+ ```ruby
75
+ product = Product.find(conditions)
76
+ product.price += 100
77
+ product.update!
78
+ ```
79
+
80
+ ```ruby
81
+ product = Product.find(conditions)
82
+ product.add(price:100).put(authors:['Andy','Bob','Charlie']).update!
83
+ ```
84
+
85
+ ## 削除
86
+ ```ruby
87
+ product = Product.find(conditions)
88
+ product.add_expected(:price,10000).delete
89
+ ```
90
+
22
91
 
23
92
  ## Contributing
24
93
 
25
- 1. Fork it ( https://github.com/[my-github-username]/dymos/fork )
94
+ 1. Fork it ( https://github.com/hoshina85/dymos/fork )
26
95
  2. Create your feature branch (`git checkout -b my-new-feature`)
27
96
  3. Commit your changes (`git commit -am 'Add some feature'`)
28
97
  4. Push to the branch (`git push origin my-new-feature`)
@@ -0,0 +1,16 @@
1
+ require 'aws-sdk-core'
2
+
3
+ module Dymos
4
+ class Client
5
+ attr_reader :client
6
+
7
+ def initialize(params={})
8
+ config = Aws.config.merge params
9
+ @client ||= Aws::DynamoDB::Client.new(config)
10
+ end
11
+
12
+ def command(name, params)
13
+ @client.send name, params
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,34 @@
1
+ require 'aws-sdk-core'
2
+
3
+ module Dymos
4
+ class Config
5
+
6
+ @default={
7
+ get_item: {},
8
+ create_table: {},
9
+ query: {},
10
+ scan: {},
11
+ put_item: {},
12
+ update_item: {},
13
+ describe_table: {},
14
+ delete_item: {},
15
+ batch_get_item: {},
16
+ batch_write_item: {},
17
+ delete_table: {},
18
+ list_tables: {},
19
+ }
20
+
21
+ class << self
22
+ attr_reader :default
23
+
24
+ def default=(config)
25
+ if Hash === config
26
+ @default = config
27
+ else
28
+ raise ArgumentError, 'configuration object must be a hash'
29
+ end
30
+ end
31
+ end
32
+
33
+ end
34
+ end
data/lib/dymos/model.rb CHANGED
@@ -7,8 +7,7 @@ module Dymos
7
7
  include ActiveModel::Dirty
8
8
  include ActiveModel::Callbacks
9
9
  include Dymos::Persistence
10
- extend Dymos::Command
11
- attr_accessor :metadata
10
+ attr_accessor :metadata, :last_execute_query
12
11
 
13
12
  define_model_callbacks :save
14
13
 
@@ -18,6 +17,36 @@ module Dymos
18
17
  super
19
18
  end
20
19
 
20
+ class << self
21
+ attr_accessor :last_execute_query
22
+
23
+ def method_missing(name, *args, &block)
24
+ methods ||= Dymos::Query::Query.instance_methods(false)+
25
+ Dymos::Query::GetItem.instance_methods(false)+
26
+ Dymos::Query::Scan.instance_methods(false)
27
+ if methods.include? name
28
+ @query||={}
29
+ @query[name]=args
30
+ self
31
+ else
32
+ super
33
+ end
34
+ end
35
+ end
36
+
37
+ def method_missing(name, *args, &block)
38
+ methods ||= Dymos::Query::UpdateItem.instance_methods(false)+
39
+ Dymos::Query::PutItem.instance_methods(false)+
40
+ Dymos::Query::DeleteItem.instance_methods(false)
41
+ if methods.include? name
42
+ @query||={}
43
+ @query[name]=args
44
+ self
45
+ else
46
+ super
47
+ end
48
+ end
49
+
21
50
  def self.field(attr, type, default: nil, desc: nil)
22
51
  fail StandardError('attribute name is invalid') if attr =~ /[\!\?]$/
23
52
  fail StandardError('require "default" option') if (type == :bool && default.nil?)
@@ -32,18 +61,18 @@ module Dymos
32
61
  define_model_callbacks attr
33
62
  define_method(attr) { |raw=false|
34
63
  run_callbacks attr do
35
- val = read_attribute(attr) || default
36
- return val if raw || !val.present?
37
- case type
38
- when :bool
39
- to_b(val)
40
- when :time
41
- Time.parse val
42
- when :integer
43
- val.to_i
44
- else
45
- val
46
- end
64
+ val = read_attribute(attr) || default
65
+ return val if raw || !val.present?
66
+ case type
67
+ when :bool
68
+ to_b(val)
69
+ when :time
70
+ Time.parse val
71
+ when :integer
72
+ val.to_i
73
+ else
74
+ val
75
+ end
47
76
  end
48
77
 
49
78
  }
@@ -61,8 +90,8 @@ module Dymos
61
90
  define_model_callbacks :"set_#{attr}"
62
91
  define_method("#{attr}=") do |value, initialize=false|
63
92
  run_callbacks :"set_#{attr}" do
64
- value = value.iso8601 if self.class.fields.include?(attr) && value.is_a?(Time)
65
- write_attribute(attr, value, initialize)
93
+ value = value.iso8601 if self.class.fields.include?(attr) && value.is_a?(Time)
94
+ write_attribute(attr, value, initialize)
66
95
  end
67
96
  end
68
97
  end
@@ -71,7 +100,6 @@ module Dymos
71
100
  @fields
72
101
  end
73
102
 
74
-
75
103
  def self.table(name)
76
104
  define_singleton_method('table_name') { name }
77
105
  define_method('table_name') { name }
@@ -94,7 +122,21 @@ module Dymos
94
122
  end
95
123
 
96
124
  def self.all
97
- self.scan.execute
125
+ if @query.present? && @query.keys & [:conditions, :add_condition, :where]
126
+ builder = Dymos::Query::Query.new.name(table_name)
127
+ @query.each do |k, v|
128
+ builder.send k, *v
129
+ end
130
+ @query={}
131
+ else
132
+ builder = Dymos::Query::Scan.new.name(table_name)
133
+ end
134
+ _execute(builder)
135
+ end
136
+
137
+ def self.one
138
+ @query[:limit] = 1
139
+ self.all.first
98
140
  end
99
141
 
100
142
  def self.find(key1, key2=nil)
@@ -102,19 +144,28 @@ module Dymos
102
144
  keys={}
103
145
  keys[indexes.first[:attribute_name].to_sym] = key1
104
146
  keys[indexes.last[:attribute_name].to_sym] = key2 if indexes.size > 1
105
- self.get.key(keys).execute
147
+
148
+ builder = Dymos::Query::GetItem.new.name(table_name).key(keys)
149
+ _execute(builder)
150
+ end
151
+ def self._execute(builder)
152
+ query = builder.build
153
+ @last_execute_query = {command: builder.command, query: query}
154
+ response = Dymos::Client.new.command builder.command, query
155
+ to_model(class_name, response)
106
156
  end
107
157
 
108
158
  def self.key_scheme
109
- @key_scheme ||= new.describe_table[:table][:key_schema]
159
+ @key_scheme ||= describe[:table][:key_schema]
110
160
  end
111
161
 
112
162
  def reload!
113
163
  reset_changes
114
164
  end
115
165
 
116
- def describe_table
117
- self.class.send(:describe).execute
166
+ def self.describe
167
+ builder=Dymos::Query::Describe.new.name(table_name)
168
+ Dymos::Client.new.command :describe_table, builder.build
118
169
  end
119
170
 
120
171
  def indexes
@@ -124,10 +175,6 @@ module Dymos
124
175
  scheme.to_h
125
176
  end
126
177
 
127
- def dynamo
128
- @client ||= Aws::DynamoDB::Client.new
129
- end
130
-
131
178
  # @return [String]
132
179
  def self.class_name
133
180
  self.name
@@ -158,5 +205,41 @@ module Dymos
158
205
  end
159
206
  end
160
207
 
208
+ def self.to_model(class_name, res)
209
+ if class_name.present?
210
+ if res.data.respond_to? :items # scan, query
211
+ metadata = extract(res, :items)
212
+ res.data[:items].map do |datum|
213
+ obj = Object.const_get(class_name).new(datum)
214
+ obj.metadata = metadata
215
+ obj.new_record = false
216
+ obj
217
+ end
218
+ elsif res.data.respond_to? :attributes # put_item, update_item
219
+ return nil if res.attributes.nil?
220
+ obj = Object.const_get(class_name).new(res.attributes)
221
+ obj.metadata = extract(res, :attributes)
222
+ obj
223
+ elsif res.respond_to? :data
224
+ if res.data.respond_to? :item # get_item, delete_item
225
+ return nil if res.data.item.nil?
226
+ obj = Object.const_get(class_name).new(res.data.item)
227
+ obj.metadata = extract(res, :item)
228
+ obj.new_record = false
229
+ obj
230
+ else
231
+ res.data.to_hash # describe
232
+ end
233
+ end
234
+ else
235
+ res.data.to_hash #list_tables
236
+ end
237
+
238
+ end
239
+
240
+ def self.extract(res, ignore_key)
241
+ keys = res.data.members.reject { |a| a == ignore_key }
242
+ keys.map { |k| [k, res.data[k]] }.to_h
243
+ end
161
244
  end
162
245
  end
@@ -21,7 +21,7 @@ module Dymos
21
21
 
22
22
  def save(*)
23
23
  run_callbacks :save do
24
- create_or_update
24
+ _put
25
25
  end
26
26
  rescue => e
27
27
  false
@@ -29,39 +29,98 @@ module Dymos
29
29
 
30
30
  def save!(*)
31
31
  run_callbacks :save do
32
- create_or_update || raise(Dymos::RecordNotSaved)
32
+ _put || raise(Dymos::RecordNotSaved)
33
+ end
34
+ end
35
+
36
+ def update(*)
37
+ run_callbacks :save do
38
+ _update
39
+ end
40
+ rescue => e
41
+ false
42
+ end
43
+
44
+ def update!(*)
45
+ run_callbacks :save do
46
+ _update || raise(Dymos::RecordNotSaved)
33
47
  end
34
48
  end
35
49
 
36
50
  def delete
37
- self.class.delete.key(indexes).execute if persisted?
51
+
52
+ if persisted?
53
+ builder = Dymos::Query::DeleteItem.new
54
+
55
+ builder.name(self.table_name).key(indexes).return_values(:all_old)
56
+
57
+ @query.each do |k, v|
58
+ builder.send k, *v
59
+ end if @query.present?
60
+ @query={}
61
+
62
+ query = builder.build
63
+ @last_execute_query = {command: builder.command, query: query}
64
+ Dymos::Client.new.command builder.command, query
65
+ end
38
66
  @destroyed = true
39
67
  freeze
40
68
  end
41
69
 
42
70
  private
43
71
 
44
- def create_or_update
45
- result = new_record? ? _create_record : _update_record
46
- result != false
47
- end
48
-
49
- def _update_record()
72
+ def _put
73
+ send :created_at=, Time.new.iso8601 if respond_to? :created_at if @new_record
50
74
  send :updated_at=, Time.new.iso8601 if respond_to? :updated_at
51
- _execute
75
+ builder = Dymos::Query::PutItem.new
76
+ builder.name(self.table_name).item(attributes).return_values(:all_old)
77
+
78
+ @query.each do |k, v|
79
+ builder.send k, *v
80
+ end if @query.present?
81
+ @query={}
82
+
83
+ _execute(builder)
52
84
  end
53
85
 
54
- def _create_record()
55
- send :created_at=, Time.new.iso8601 if respond_to? :created_at
86
+ def _update
56
87
  send :updated_at=, Time.new.iso8601 if respond_to? :updated_at
57
- _execute
88
+ builder = Dymos::Query::UpdateItem.new
89
+
90
+ builder.name(self.table_name).key(indexes).return_values(:all_old)
91
+
92
+ self.changes.each do |column, change|
93
+ builder.put(column, change[1])
94
+ end
95
+
96
+ @query.each do |k, v|
97
+ builder.send k, *v
98
+ end if @query.present?
99
+ @query={}
100
+
101
+ _execute(builder)
58
102
  end
59
103
 
60
- def _execute()
61
- result = self.class.put.item(attributes).execute
104
+ #
105
+ # def _update_record()
106
+ # send :updated_at=, Time.new.iso8601 if respond_to? :updated_at
107
+ # _execute
108
+ # end
109
+ #
110
+ # def _create_record()
111
+ # send :created_at=, Time.new.iso8601 if respond_to? :created_at
112
+ # send :updated_at=, Time.new.iso8601 if respond_to? :updated_at
113
+ # _execute
114
+ # end
115
+
116
+ def _execute(builder)
117
+ query = builder.build
118
+ @last_execute_query = {command: builder.command, query: query}
119
+ response = Dymos::Client.new.command builder.command, query
120
+ fail raise(Dymos::RecordNotSaved) if response.nil?
62
121
  changes_applied
63
122
  @new_record = false
64
- result
123
+ response.present?
65
124
  end
66
125
 
67
126
  end
@@ -0,0 +1,23 @@
1
+ module Dymos
2
+ module Query
3
+ class Base
4
+ def initialize
5
+ @query={}
6
+ end
7
+
8
+ def command
9
+
10
+ end
11
+
12
+ def name(value)
13
+ @query[:table_name] = value
14
+ self
15
+ end
16
+
17
+ def build(value={})
18
+ value = Dymos::Config.default[command.to_sym].merge value
19
+ @query.merge value
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,72 @@
1
+ module Dymos
2
+ module Query
3
+ class CreateTable < Base
4
+ def command
5
+ 'create_table'
6
+ end
7
+
8
+ def attributes(value)
9
+ @query[:attribute_definitions] = _attributes(value)
10
+ self
11
+ end
12
+
13
+ private def _attributes(value)
14
+ value.map { |k, v|
15
+ {attribute_name: k.to_s, attribute_type: v.to_s}
16
+ }
17
+ end
18
+
19
+ def keys(value)
20
+ @query[:key_schema]=_keys(value)
21
+ self
22
+ end
23
+
24
+ private def _keys(value)
25
+ value.map { |k, v|
26
+ {attribute_name: k.to_s, key_type: v.to_s}
27
+ }
28
+ end
29
+
30
+ def throughput(value)
31
+ @query[:provisioned_throughput] = _throughput(value)
32
+ self
33
+ end
34
+
35
+ private def _throughput(value)
36
+ {
37
+ read_capacity_units: value[:read],
38
+ write_capacity_units: value[:write]
39
+ }
40
+ end
41
+
42
+ def gsi(value)
43
+ @query[:global_secondary_indexes] = value.map { |i|
44
+ index = _index(i)
45
+ index[:provisioned_throughput] = _throughput(i[:throughput])
46
+ index
47
+ }
48
+ self
49
+ end
50
+
51
+ def lsi(value)
52
+ @query[:local_secondary_indexes] = value.map do |i|
53
+ _index(i)
54
+ end
55
+ self
56
+ end
57
+
58
+ private def _index(i)
59
+ index = {}
60
+ index[:index_name] = i[:name]
61
+ index[:key_schema] = _keys(i[:keys])
62
+ index[:projection]= _projection_type(i)
63
+ index[:projection][:non_key_attributes] = i[:projection][:attributes] if i.try(:[], :projection).try(:[], :attributes).present?
64
+ index
65
+ end
66
+
67
+ private def _projection_type(i)
68
+ {projection_type: (i.try(:[], :projection).try(:[], :type) || 'ALL').to_s}
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,47 +1,75 @@
1
1
  module Dymos
2
2
  module Query
3
- class DeleteItem < ::Dymos::Query::Builder
3
+ class DeleteItem < Base
4
+ def command
5
+ 'delete_item'
6
+ end
4
7
 
5
- # @param [String] name
6
- # @return [self]
7
- def key(name)
8
- @key = name
8
+ def key(value)
9
+ @query[:key] = value.deep_stringify_keys
9
10
  self
10
11
  end
11
12
 
12
- def expected(params)
13
- @expected = Hash[params.map do |name, expression|
14
- operator, values = expression.split(' ', 2)
15
- if values.nil?
16
- [name, ::Dymos::Query::Expect.new.condition(operator, nil).data]
17
- else
18
- value1, value2 = values.split(' ')
19
- if value2.present?
20
- [name, ::Dymos::Query::Expect.new.condition(operator, values).data]
21
- else
22
- [name, ::Dymos::Query::Expect.new.condition(operator, value1).data]
23
- end
24
- end
13
+ def expected(value)
14
+ value.map { |v| add_expected(*v) }
15
+ self
16
+ end
25
17
 
26
- end]
18
+ def add_expected(*value)
19
+ if value.count == 2
20
+ column, operator, value = value[0], :eq, value[1]
21
+ else
22
+ column, operator, value = value
23
+ end
24
+ @query[:expected] ||= {}
25
+ @query[:expected].store(*_add_expected(column, operator, value))
27
26
  self
28
27
  end
29
28
 
30
- def query
31
- data = {
32
- table_name: @table_name.to_s,
33
- key: @key,
34
- return_values: @return_values || 'ALL_OLD'
35
- }
29
+ def _add_expected(column, operator, value)
30
+ [column.to_s, {
31
+ attribute_value_list: ([:BETWEEN, :IN].include? operator) ? [*value] : [value],
32
+ comparison_operator: operator.to_s.upcase
33
+ }
34
+ ]
35
+ end
36
36
 
37
- if @expected.present?
38
- data[:expected] = @expected
39
- if @expected.size > 1
40
- data[:conditional_operator] = @conditional_operator || 'AND'
41
- end
42
- end
43
- data
37
+ def conditional_operator(value)
38
+ @query[:conditional_operator] = value.to_s.upcase
39
+ self
40
+ end
41
+
42
+
43
+ def return_values(value)
44
+ @query[:return_values] = value.to_s.upcase
45
+ self
46
+ end
47
+
48
+ def return_consumed_capacity(value)
49
+ @query[:return_consumed_capacity] = value.to_s.upcase
50
+ self
44
51
  end
52
+
53
+ def return_item_collection_metrics(value)
54
+ @query[:return_item_collection_metrics] = value.to_s.upcase
55
+ self
56
+ end
57
+
58
+ def condition_expression(value)
59
+ @query[:condition_expression] = value
60
+ self
61
+ end
62
+
63
+ def expression_attribute_names(value)
64
+ @query[:expression_attribute_names] = value.deep_stringify_keys
65
+ self
66
+ end
67
+
68
+ def expression_attribute_values(value)
69
+ @query[:expression_attribute_values] = value.deep_stringify_keys
70
+ self
71
+ end
72
+
45
73
  end
46
74
  end
47
75
  end
@@ -1,10 +1,8 @@
1
1
  module Dymos
2
2
  module Query
3
- class Describe < ::Dymos::Query::Builder
4
- def query
5
- {
6
- table_name: @table_name.to_s
7
- }
3
+ class Describe < Base
4
+ def command
5
+ 'describe_table'
8
6
  end
9
7
  end
10
8
  end