standardapi 6.0.0.15 → 6.0.0.29
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 +15 -6
- data/lib/standard_api.rb +2 -0
- data/lib/standard_api/active_record/connection_adapters/postgresql/schema_statements.rb +21 -0
- data/lib/standard_api/controller.rb +77 -66
- data/lib/standard_api/errors.rb +13 -0
- data/lib/standard_api/helpers.rb +67 -15
- data/lib/standard_api/includes.rb +22 -12
- data/lib/standard_api/orders.rb +4 -6
- data/lib/standard_api/railtie.rb +1 -1
- data/lib/standard_api/route_helpers.rb +4 -0
- data/lib/standard_api/test_case/calculate_tests.rb +5 -3
- data/lib/standard_api/test_case/create_tests.rb +0 -3
- data/lib/standard_api/test_case/schema_tests.rb +19 -3
- data/lib/standard_api/version.rb +1 -1
- data/lib/standard_api/views/application/_record.json.jbuilder +11 -10
- data/lib/standard_api/views/application/_record.streamer +11 -10
- data/lib/standard_api/views/application/_schema.json.jbuilder +68 -0
- data/lib/standard_api/views/application/_schema.streamer +78 -0
- data/lib/standard_api/views/application/index.json.jbuilder +9 -16
- data/lib/standard_api/views/application/index.streamer +9 -16
- data/lib/standard_api/views/application/schema.json.jbuilder +1 -12
- data/lib/standard_api/views/application/schema.streamer +1 -16
- data/lib/standard_api/views/application/show.json.jbuilder +8 -1
- data/lib/standard_api/views/application/show.streamer +8 -1
- data/test/standard_api/test_app.rb +55 -0
- data/test/standard_api/test_app/config/database.yml +4 -0
- data/test/standard_api/test_app/controllers.rb +107 -0
- data/test/standard_api/test_app/models.rb +94 -0
- data/test/standard_api/test_app/test/factories.rb +50 -0
- data/test/standard_api/test_app/test/fixtures/photo.png +0 -0
- data/test/standard_api/test_app/views/photos/_photo.json.jbuilder +15 -0
- data/test/standard_api/test_app/views/photos/_photo.streamer +17 -0
- data/test/standard_api/test_app/views/photos/_schema.json.jbuilder +1 -0
- data/test/standard_api/test_app/views/photos/_schema.streamer +3 -0
- data/test/standard_api/test_app/views/photos/schema.json.jbuilder +1 -0
- data/test/standard_api/test_app/views/photos/schema.streamer +1 -0
- data/test/standard_api/test_app/views/properties/edit.html.erb +1 -0
- data/test/standard_api/test_app/views/sessions/new.html.erb +0 -0
- metadata +27 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3670132e90418137f095c8e7741310e2911bfde21e78579e27ea6c54ae88d0f1
|
4
|
+
data.tar.gz: 205778759e7188eda509e289495a383d6a5ff037116fd5043a519f95c5b7222d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d4a009d0ea47b18ebc5088d81bdf4518e9a22749b1ea0a17e8f7b5504be42dbeea60945ad75eeb5a4cdfda866f39edc12391262ff64b2a5cc3748011cb0c4bc
|
7
|
+
data.tar.gz: 49a638815647e3fbe6d63dc4eda87eda4703425b2c36e4565763cc0aad1abf0934d54d8f18858d00ac733f1e4662873f5ff586e1cdf27aafdaebfbc825703b71
|
data/README.md
CHANGED
@@ -105,11 +105,12 @@ including the author, the photos that the author took can also be included.
|
|
105
105
|
# API Usage
|
106
106
|
Resources can be queried via REST style end points
|
107
107
|
```
|
108
|
-
GET /records/:id
|
109
|
-
PATCH /records/:id
|
110
|
-
GET /records
|
111
|
-
|
112
|
-
|
108
|
+
GET /records/:id fetch record
|
109
|
+
PATCH /records/:id update record
|
110
|
+
GET /records/ fetch records
|
111
|
+
GET /records/calculate apply count and other functions on record(s)
|
112
|
+
POST /records create record
|
113
|
+
DELETE /records destroy record
|
113
114
|
```
|
114
115
|
|
115
116
|
All resource end points can be filtered, ordered, limited, offset, and have includes. All options are passed via query string in a nested URI encoded format.
|
@@ -163,8 +164,16 @@ location: {within: 0106000020e6...} WHERE ST_Within("listings"."location
|
|
163
164
|
|
164
165
|
// On Relationships
|
165
166
|
property: {size: 10000} JOIN properties WHERE properties.size = 10000"
|
167
|
+
```
|
168
|
+
## Calculations
|
169
|
+
|
170
|
+
The only change on calculate routes is the `selects` paramater contains the functions to apply. Currently just `minimum`, `maximum`, `average`, `sum`, and `count`.
|
166
171
|
|
167
|
-
|
172
|
+
```
|
173
|
+
{ count: '*' } SELECT COUNT(*)
|
174
|
+
[{ count: '*' }] SELECT COUNT(*)
|
175
|
+
[{ count: '*', maximum: :id, minimum: :id }] SELECT COUNT(*), MAXIMUM(id), MINIMUM(id)
|
176
|
+
[{ maximum: :id }, { maximum: :count }] SELECT MAXIMUM(id), MAXIMUM(count)
|
168
177
|
```
|
169
178
|
|
170
179
|
# Testing
|
data/lib/standard_api.rb
CHANGED
@@ -8,9 +8,11 @@ require 'active_record/sort'
|
|
8
8
|
require 'active_support/core_ext/hash/indifferent_access'
|
9
9
|
|
10
10
|
require 'standard_api/version'
|
11
|
+
require 'standard_api/errors'
|
11
12
|
require 'standard_api/orders'
|
12
13
|
require 'standard_api/includes'
|
13
14
|
require 'standard_api/controller'
|
14
15
|
require 'standard_api/helpers'
|
15
16
|
require 'standard_api/route_helpers'
|
17
|
+
require 'standard_api/active_record/connection_adapters/postgresql/schema_statements'
|
16
18
|
require 'standard_api/railtie'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
class PostgreSQLAdapter < AbstractAdapter
|
4
|
+
|
5
|
+
# Returns a comment stored in database for given table
|
6
|
+
def database_comment(database_name=nil) # :nodoc:
|
7
|
+
database_name ||= current_database
|
8
|
+
|
9
|
+
scope = quoted_scope(database_name, type: "BASE TABLE")
|
10
|
+
if scope[:name]
|
11
|
+
query_value(<<~SQL, "SCHEMA")
|
12
|
+
SELECT pg_catalog.shobj_description(d.oid, 'pg_database')
|
13
|
+
FROM pg_catalog.pg_database d
|
14
|
+
WHERE datname = #{scope[:name]};
|
15
|
+
SQL
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,26 +1,36 @@
|
|
1
1
|
module StandardAPI
|
2
2
|
module Controller
|
3
3
|
|
4
|
+
delegate :preloadables, to: :helpers
|
5
|
+
|
4
6
|
def self.included(klass)
|
5
|
-
klass.helper_method :includes, :orders, :model, :resource_limit,
|
6
|
-
:default_limit
|
7
|
+
klass.helper_method :includes, :orders, :model, :models, :resource_limit,
|
8
|
+
:default_limit
|
7
9
|
klass.before_action :set_standardapi_headers
|
10
|
+
klass.rescue_from StandardAPI::UnpermittedParameters, with: :bad_request
|
8
11
|
klass.append_view_path(File.join(File.dirname(__FILE__), 'views'))
|
9
12
|
klass.extend(ClassMethods)
|
10
13
|
end
|
11
14
|
|
12
15
|
def tables
|
13
|
-
Rails.application.eager_load! if Rails.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
render json:
|
16
|
+
Rails.application.eager_load! if !Rails.application.config.eager_load
|
17
|
+
|
18
|
+
tables = ApplicationController.descendants
|
19
|
+
tables.select! { |c| c.ancestors.include?(self.class) && c != self.class }
|
20
|
+
tables.map!(&:model).compact!
|
21
|
+
tables.map!(&:table_name)
|
22
|
+
render json: tables
|
23
|
+
end
|
24
|
+
|
25
|
+
if Rails.env == 'development'
|
26
|
+
def schema
|
27
|
+
Rails.application.eager_load! if !Rails.application.config.eager_load
|
28
|
+
end
|
20
29
|
end
|
21
30
|
|
22
31
|
def index
|
23
|
-
|
32
|
+
records = preloadables(resources.limit(limit).offset(params[:offset]).sort(orders), includes)
|
33
|
+
instance_variable_set("@#{model.model_name.plural}", records)
|
24
34
|
end
|
25
35
|
|
26
36
|
def calculate
|
@@ -32,12 +42,13 @@ module StandardAPI
|
|
32
42
|
end
|
33
43
|
end
|
34
44
|
@calculations = Hash[@calculations] if @calculations[0].is_a?(Array) && params[:group_by]
|
35
|
-
|
45
|
+
|
36
46
|
render json: @calculations
|
37
47
|
end
|
38
48
|
|
39
49
|
def show
|
40
|
-
|
50
|
+
record = preloadables(resources, includes).find(params[:id])
|
51
|
+
instance_variable_set("@#{model.model_name.singular}", record)
|
41
52
|
end
|
42
53
|
|
43
54
|
def new
|
@@ -93,13 +104,40 @@ module StandardAPI
|
|
93
104
|
head :no_content
|
94
105
|
end
|
95
106
|
|
107
|
+
def remove_resource
|
108
|
+
resource = resources.find(params[:id])
|
109
|
+
subresource_class = resource.association(params[:relationship]).klass
|
110
|
+
subresource = subresource_class.find_by_id(params[:resource_id])
|
111
|
+
|
112
|
+
if(subresource)
|
113
|
+
result = resource.send(params[:relationship]).delete(subresource)
|
114
|
+
head result ? :no_content : :bad_request
|
115
|
+
else
|
116
|
+
head :not_found
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def add_resource
|
121
|
+
resource = resources.find(params[:id])
|
122
|
+
|
123
|
+
subresource_class = resource.association(params[:relationship]).klass
|
124
|
+
subresource = subresource_class.find_by_id(params[:resource_id])
|
125
|
+
if(subresource)
|
126
|
+
result = resource.send(params[:relationship]) << subresource
|
127
|
+
head result ? :created : :bad_request
|
128
|
+
else
|
129
|
+
head :not_found
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
96
134
|
# Override if you want to support masking
|
97
135
|
def current_mask
|
98
136
|
@current_mask ||= {}
|
99
137
|
end
|
100
138
|
|
101
139
|
module ClassMethods
|
102
|
-
|
140
|
+
|
103
141
|
def model
|
104
142
|
return @model if defined?(@model)
|
105
143
|
@model = name.sub(/Controller\z/, '').singularize.camelize.safe_constantize
|
@@ -109,6 +147,10 @@ module StandardAPI
|
|
109
147
|
|
110
148
|
private
|
111
149
|
|
150
|
+
def bad_request(exception)
|
151
|
+
render body: exception.to_s, status: :bad_request
|
152
|
+
end
|
153
|
+
|
112
154
|
def set_standardapi_headers
|
113
155
|
headers['StandardAPI-Version'] = StandardAPI::VERSION
|
114
156
|
end
|
@@ -117,6 +159,15 @@ module StandardAPI
|
|
117
159
|
self.class.model
|
118
160
|
end
|
119
161
|
|
162
|
+
def models
|
163
|
+
return @models if defined?(@models)
|
164
|
+
Rails.application.eager_load! if !Rails.application.config.eager_load
|
165
|
+
|
166
|
+
@models = ApplicationController.descendants
|
167
|
+
@models.select! { |c| c.ancestors.include?(self.class) && c != self.class }
|
168
|
+
@models.map!(&:model).compact!
|
169
|
+
end
|
170
|
+
|
120
171
|
def model_includes
|
121
172
|
if self.respond_to?("#{model.model_name.singular}_includes", true)
|
122
173
|
self.send("#{model.model_name.singular}_includes")
|
@@ -156,81 +207,39 @@ module StandardAPI
|
|
156
207
|
|
157
208
|
def resources
|
158
209
|
query = model.filter(params['where']).filter(current_mask[model.table_name])
|
159
|
-
|
210
|
+
|
160
211
|
if params[:distinct_on]
|
161
212
|
query = query.distinct_on(params[:distinct_on])
|
162
213
|
elsif params[:distinct]
|
163
214
|
query = query.distinct
|
164
215
|
end
|
165
|
-
|
216
|
+
|
166
217
|
if params[:join]
|
167
218
|
query = query.joins(params[:join].to_sym)
|
168
219
|
end
|
169
|
-
|
220
|
+
|
170
221
|
if params[:group_by]
|
171
222
|
query = query.group(params[:group_by])
|
172
223
|
end
|
173
|
-
|
224
|
+
|
174
225
|
query
|
175
226
|
end
|
176
227
|
|
177
228
|
def includes
|
178
|
-
@includes ||= StandardAPI::Includes.
|
179
|
-
end
|
180
|
-
|
181
|
-
def preloadables(record, iclds)
|
182
|
-
preloads = {}
|
183
|
-
|
184
|
-
iclds.each do |key, value|
|
185
|
-
if reflection = record.klass.reflections[key]
|
186
|
-
case value
|
187
|
-
when true
|
188
|
-
preloads[key] = value
|
189
|
-
when Hash, ActiveSupport::HashWithIndifferentAccess
|
190
|
-
if !value.keys.any? { |x| ['when', 'where', 'limit', 'offset', 'order', 'distinct'].include?(x) }
|
191
|
-
if !reflection.polymorphic?
|
192
|
-
preloads[key] = preloadables_hash(reflection.klass, value)
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
preloads.empty? ? record : record.preload(preloads)
|
200
|
-
end
|
201
|
-
|
202
|
-
def preloadables_hash(klass, iclds)
|
203
|
-
preloads = {}
|
204
|
-
|
205
|
-
iclds.each do |key, value|
|
206
|
-
if reflection = klass.reflections[key]
|
207
|
-
case value
|
208
|
-
when true
|
209
|
-
preloads[key] = value
|
210
|
-
when Hash, ActiveSupport::HashWithIndifferentAccess
|
211
|
-
if !value.keys.any? { |x| ['when', 'where', 'limit', 'offset', 'order', 'distinct'].include?(x) }
|
212
|
-
if !reflection.polymorphic?
|
213
|
-
preloads[key] = preloadables_hash(reflection.klass, value)
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
preloads
|
229
|
+
@includes ||= StandardAPI::Includes.sanitize(params[:include], model_includes)
|
221
230
|
end
|
222
|
-
|
231
|
+
|
223
232
|
def required_orders
|
224
233
|
[]
|
225
234
|
end
|
226
|
-
|
235
|
+
|
227
236
|
def default_orders
|
228
237
|
nil
|
229
238
|
end
|
230
239
|
|
231
240
|
def orders
|
232
241
|
exluded_required_orders = required_orders.map(&:to_s)
|
233
|
-
|
242
|
+
|
234
243
|
case params[:order]
|
235
244
|
when Hash, ActionController::Parameters
|
236
245
|
exluded_required_orders -= params[:order].keys.map(&:to_s)
|
@@ -246,7 +255,7 @@ module StandardAPI
|
|
246
255
|
when String
|
247
256
|
exluded_required_orders.delete(params[:order])
|
248
257
|
end
|
249
|
-
|
258
|
+
|
250
259
|
if !exluded_required_orders.empty?
|
251
260
|
params[:order] = exluded_required_orders.unshift(params[:order])
|
252
261
|
end
|
@@ -304,10 +313,12 @@ module StandardAPI
|
|
304
313
|
@model = parts[0].singularize.camelize.constantize
|
305
314
|
column = parts[1]
|
306
315
|
end
|
307
|
-
|
316
|
+
|
308
317
|
column = column == '*' ? Arel.star : column.to_sym
|
309
318
|
if functions.include?(func.to_s.downcase)
|
310
|
-
|
319
|
+
node = (defined?(@model) ? @model : model).arel_table[column].send(func)
|
320
|
+
node.distinct = true if params[:distinct]
|
321
|
+
@selects << node
|
311
322
|
end
|
312
323
|
end
|
313
324
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module StandardAPI
|
2
|
+
class StandardAPIError < StandardError
|
3
|
+
end
|
4
|
+
|
5
|
+
class UnpermittedParameters < StandardAPIError
|
6
|
+
attr_reader :params
|
7
|
+
|
8
|
+
def initialize(params)
|
9
|
+
@params = params
|
10
|
+
super("found unpermitted parameter#{'s' if params.size > 1 }: #{params.map { |e| e.inspect }.join(", ")}")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/standard_api/helpers.rb
CHANGED
@@ -1,6 +1,58 @@
|
|
1
1
|
module StandardAPI
|
2
2
|
module Helpers
|
3
|
-
|
3
|
+
|
4
|
+
def preloadables(record, includes)
|
5
|
+
preloads = {}
|
6
|
+
|
7
|
+
includes.each do |key, value|
|
8
|
+
if reflection = record.klass.reflections[key]
|
9
|
+
case value
|
10
|
+
when true
|
11
|
+
preloads[key] = value
|
12
|
+
when Hash, ActiveSupport::HashWithIndifferentAccess
|
13
|
+
if !value.keys.any? { |x| ['when', 'where', 'limit', 'offset', 'order', 'distinct'].include?(x) }
|
14
|
+
if !reflection.polymorphic?
|
15
|
+
preloads[key] = preloadables_hash(reflection.klass, value)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
preloads.empty? ? record : record.preload(preloads)
|
23
|
+
end
|
24
|
+
|
25
|
+
def preloadables_hash(klass, iclds)
|
26
|
+
preloads = {}
|
27
|
+
|
28
|
+
iclds.each do |key, value|
|
29
|
+
if reflection = klass.reflections[key]
|
30
|
+
case value
|
31
|
+
when true
|
32
|
+
preloads[key] = value
|
33
|
+
when Hash, ActiveSupport::HashWithIndifferentAccess
|
34
|
+
if !value.keys.any? { |x| ['when', 'where', 'limit', 'offset', 'order', 'distinct'].include?(x) }
|
35
|
+
if !reflection.polymorphic?
|
36
|
+
preloads[key] = preloadables_hash(reflection.klass, value)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
preloads
|
44
|
+
end
|
45
|
+
|
46
|
+
def schema_partial(model)
|
47
|
+
path = model.model_name.plural
|
48
|
+
|
49
|
+
if lookup_context.exists?("schema", path, true)
|
50
|
+
[path, "schema"].join('/')
|
51
|
+
else
|
52
|
+
'application/schema'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
4
56
|
def model_partial(record)
|
5
57
|
if lookup_context.exists?(record.model_name.element, record.model_name.plural, true)
|
6
58
|
[record.model_name.plural, record.model_name.element].join('/')
|
@@ -17,7 +69,7 @@ module StandardAPI
|
|
17
69
|
false
|
18
70
|
end
|
19
71
|
end
|
20
|
-
|
72
|
+
|
21
73
|
def cache_key(record, includes)
|
22
74
|
timestamp_keys = ['cached_at'] + record.class.column_names.select{|x| x.ends_with? "_cached_at"}
|
23
75
|
if includes.empty?
|
@@ -27,7 +79,7 @@ module StandardAPI
|
|
27
79
|
"#{record.model_name.cache_key}/#{record.id}-#{digest_hash(sort_hash(includes))}-#{timestamp.utc.to_s(record.cache_timestamp_format)}"
|
28
80
|
end
|
29
81
|
end
|
30
|
-
|
82
|
+
|
31
83
|
def can_cache_relation?(klass, relation, subincludes)
|
32
84
|
cache_columns = ["#{relation}_cached_at"] + cached_at_columns_for_includes(subincludes).map {|c| "#{relation}_#{c}"}
|
33
85
|
if (cache_columns - klass.column_names).empty?
|
@@ -36,12 +88,12 @@ module StandardAPI
|
|
36
88
|
false
|
37
89
|
end
|
38
90
|
end
|
39
|
-
|
91
|
+
|
40
92
|
def association_cache_key(record, relation, subincludes)
|
41
93
|
timestamp = ["#{relation}_cached_at"] + cached_at_columns_for_includes(subincludes).map {|c| "#{relation}_#{c}"}
|
42
94
|
timestamp.map! { |col| record.send(col) }
|
43
95
|
timestamp = timestamp.max
|
44
|
-
|
96
|
+
|
45
97
|
case association = record.class.reflect_on_association(relation)
|
46
98
|
when ActiveRecord::Reflection::HasManyReflection, ActiveRecord::Reflection::HasAndBelongsToManyReflection, ActiveRecord::Reflection::HasOneReflection, ActiveRecord::Reflection::ThroughReflection
|
47
99
|
"#{record.model_name.cache_key}/#{record.id}/#{includes_to_cache_key(relation, subincludes)}-#{timestamp.utc.to_s(record.cache_timestamp_format)}"
|
@@ -56,13 +108,13 @@ module StandardAPI
|
|
56
108
|
raise ArgumentError, 'Unkown association type'
|
57
109
|
end
|
58
110
|
end
|
59
|
-
|
111
|
+
|
60
112
|
def cached_at_columns_for_includes(includes)
|
61
|
-
includes.select { |k,v| !['when', 'where', 'limit', 'order', 'distinct'].include?(k) }.map do |k, v|
|
113
|
+
includes.select { |k,v| !['when', 'where', 'limit', 'order', 'distinct', 'distinct_on'].include?(k) }.map do |k, v|
|
62
114
|
["#{k}_cached_at"] + cached_at_columns_for_includes(v).map { |v2| "#{k}_#{v2}" }
|
63
115
|
end.flatten
|
64
116
|
end
|
65
|
-
|
117
|
+
|
66
118
|
def includes_to_cache_key(relation, subincludes)
|
67
119
|
if subincludes.empty?
|
68
120
|
relation.to_s
|
@@ -70,7 +122,7 @@ module StandardAPI
|
|
70
122
|
"#{relation}-#{digest_hash(sort_hash(subincludes))}"
|
71
123
|
end
|
72
124
|
end
|
73
|
-
|
125
|
+
|
74
126
|
def sort_hash(hash)
|
75
127
|
hash.keys.sort.reduce({}) do |seed, key|
|
76
128
|
if seed[key].is_a?(Hash)
|
@@ -81,7 +133,7 @@ module StandardAPI
|
|
81
133
|
seed
|
82
134
|
end
|
83
135
|
end
|
84
|
-
|
136
|
+
|
85
137
|
def digest_hash(*hashes)
|
86
138
|
hashes.compact!
|
87
139
|
hashes.map! { |h| sort_hash(h) }
|
@@ -103,8 +155,6 @@ module StandardAPI
|
|
103
155
|
|
104
156
|
def json_column_type(sql_type)
|
105
157
|
case sql_type
|
106
|
-
when /character varying(\(\d+\))?/
|
107
|
-
'string'
|
108
158
|
when 'timestamp without time zone'
|
109
159
|
'datetime'
|
110
160
|
when 'time without time zone'
|
@@ -133,12 +183,14 @@ module StandardAPI
|
|
133
183
|
'string'
|
134
184
|
when 'boolean'
|
135
185
|
'boolean'
|
136
|
-
when 'geometry'
|
137
|
-
'ewkb'
|
138
186
|
when 'uuid' # TODO: should be uuid
|
139
187
|
'string'
|
188
|
+
when /character varying(\(\d+\))?/
|
189
|
+
'string'
|
190
|
+
when /^geometry/
|
191
|
+
'ewkb'
|
140
192
|
end
|
141
193
|
end
|
142
194
|
|
143
195
|
end
|
144
|
-
end
|
196
|
+
end
|