fmrest 0.9.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -0
- data/README.md +94 -17
- data/UPGRADING +15 -0
- data/fmrest.gemspec +16 -5
- data/lib/fmrest.rb +10 -3
- data/lib/fmrest/connection_settings.rb +124 -0
- data/lib/fmrest/errors.rb +2 -0
- data/lib/fmrest/spyke/base.rb +0 -12
- data/lib/fmrest/spyke/container_field.rb +2 -2
- data/lib/fmrest/spyke/model.rb +3 -6
- data/lib/fmrest/spyke/model/associations.rb +15 -11
- data/lib/fmrest/spyke/model/attributes.rb +21 -29
- data/lib/fmrest/spyke/model/auth.rb +8 -0
- data/lib/fmrest/spyke/model/connection.rb +122 -24
- data/lib/fmrest/spyke/model/container_fields.rb +15 -0
- data/lib/fmrest/spyke/model/http.rb +42 -2
- data/lib/fmrest/spyke/model/orm.rb +61 -17
- data/lib/fmrest/spyke/model/record_id.rb +78 -0
- data/lib/fmrest/spyke/model/serialization.rb +26 -7
- data/lib/fmrest/spyke/model/uri.rb +3 -4
- data/lib/fmrest/spyke/spyke_formatter.rb +5 -5
- data/lib/fmrest/string_date.rb +46 -7
- data/lib/fmrest/token_store.rb +6 -0
- data/lib/fmrest/token_store/base.rb +3 -3
- data/lib/fmrest/token_store/null.rb +20 -0
- data/lib/fmrest/v1.rb +8 -4
- data/lib/fmrest/v1/auth.rb +30 -0
- data/lib/fmrest/v1/connection.rb +51 -25
- data/lib/fmrest/v1/dates.rb +81 -0
- data/lib/fmrest/v1/raise_errors.rb +3 -3
- data/lib/fmrest/v1/token_session.rb +41 -50
- data/lib/fmrest/v1/type_coercer.rb +111 -36
- data/lib/fmrest/v1/utils.rb +0 -17
- data/lib/fmrest/version.rb +1 -1
- metadata +41 -19
@@ -5,17 +5,18 @@ require "fmrest/string_date"
|
|
5
5
|
module FmRest
|
6
6
|
module V1
|
7
7
|
class TypeCoercer < Faraday::Response::Middleware
|
8
|
-
# We use this date to represent a time for consistency with
|
8
|
+
# We use this date to represent a FileMaker time for consistency with
|
9
|
+
# ginjo-rfm
|
9
10
|
JULIAN_ZERO_DAY = "-4712/1/1"
|
10
11
|
|
11
12
|
COERCE_HYBRID = [:hybrid, "hybrid", true].freeze
|
12
13
|
COERCE_FULL = [:full, "full"].freeze
|
13
14
|
|
14
15
|
# @param app [#call]
|
15
|
-
# @param
|
16
|
-
def initialize(app,
|
16
|
+
# @param settings [FmRest::ConnectionSettings]
|
17
|
+
def initialize(app, settings)
|
17
18
|
super(app)
|
18
|
-
@
|
19
|
+
@settings = settings
|
19
20
|
end
|
20
21
|
|
21
22
|
def on_complete(env)
|
@@ -30,15 +31,13 @@ module FmRest
|
|
30
31
|
field_data = record["fieldData"] || record[:fieldData]
|
31
32
|
portal_data = record["portalData"] || record[:portalData]
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
34
|
+
coerce_fields(field_data)
|
35
|
+
|
36
|
+
portal_data.try(:each_value) do |portal_records|
|
37
|
+
portal_records.each do |pr|
|
38
|
+
coerce_fields(pr)
|
38
39
|
end
|
39
40
|
end
|
40
|
-
|
41
|
-
enum.each { |hash| coerce_fields(hash) }
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|
@@ -49,29 +48,49 @@ module FmRest
|
|
49
48
|
next unless v.is_a?(String)
|
50
49
|
next if k == "recordId" || k == :recordId || k == "modId" || k == :modId
|
51
50
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
51
|
+
if quick_check_timestamp(v)
|
52
|
+
begin
|
53
|
+
hash[k] = coerce_timestamp(v)
|
54
|
+
next
|
55
|
+
rescue ArgumentError
|
56
|
+
end
|
57
57
|
end
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
if quick_check_date(v)
|
60
|
+
begin
|
61
|
+
hash[k] = date_class.strptime(v, date_strptime_format)
|
62
|
+
next
|
63
|
+
rescue ArgumentError
|
64
|
+
end
|
64
65
|
end
|
65
66
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
67
|
+
if quick_check_time(v)
|
68
|
+
begin
|
69
|
+
hash[k] = datetime_class.strptime("#{JULIAN_ZERO_DAY} #{v}", time_strptime_format)
|
70
|
+
next
|
71
|
+
rescue ArgumentError
|
72
|
+
end
|
71
73
|
end
|
72
74
|
end
|
73
75
|
end
|
74
76
|
|
77
|
+
def coerce_timestamp(str)
|
78
|
+
str_timestamp = DateTime.strptime(str, datetime_strptime_format)
|
79
|
+
|
80
|
+
if local_timezone?
|
81
|
+
# Change the DateTime to the local timezone, keeping the same
|
82
|
+
# time and just modifying the timezone
|
83
|
+
offset = FmRest::V1.local_offset_for_datetime(str_timestamp)
|
84
|
+
str_timestamp = str_timestamp.new_offset(offset) - offset
|
85
|
+
end
|
86
|
+
|
87
|
+
if datetime_class == StringDateTime
|
88
|
+
str_timestamp = StringDateTime.new(str, str_timestamp)
|
89
|
+
end
|
90
|
+
|
91
|
+
str_timestamp
|
92
|
+
end
|
93
|
+
|
75
94
|
def date_class
|
76
95
|
@date_class ||=
|
77
96
|
case coerce_dates
|
@@ -92,23 +111,79 @@ module FmRest
|
|
92
111
|
end
|
93
112
|
end
|
94
113
|
|
95
|
-
def
|
96
|
-
@date_format
|
97
|
-
|
114
|
+
def date_fm_format
|
115
|
+
@settings.date_format
|
116
|
+
end
|
117
|
+
|
118
|
+
def timestamp_fm_format
|
119
|
+
@settings.timestamp_format
|
120
|
+
end
|
121
|
+
|
122
|
+
def time_fm_format
|
123
|
+
@settings.time_format
|
98
124
|
end
|
99
125
|
|
100
|
-
def
|
101
|
-
|
102
|
-
|
126
|
+
def date_strptime_format
|
127
|
+
FmRest::V1.fm_date_to_strptime_format(date_fm_format)
|
128
|
+
end
|
129
|
+
|
130
|
+
def datetime_strptime_format
|
131
|
+
FmRest::V1.fm_date_to_strptime_format(timestamp_fm_format)
|
132
|
+
end
|
133
|
+
|
134
|
+
def time_strptime_format
|
135
|
+
@time_strptime_format ||=
|
136
|
+
"%Y/%m/%d " + FmRest::V1.fm_date_to_strptime_format(time_fm_format)
|
137
|
+
end
|
138
|
+
|
139
|
+
# We use a string length test, followed by regexp match test to try to
|
140
|
+
# identify date fields. Benchmarking shows this should be between 1 and 3
|
141
|
+
# orders of magnitude faster for fails (i.e. non-dates) than just using
|
142
|
+
# Date.strptime.
|
143
|
+
#
|
144
|
+
# user system total real
|
145
|
+
# strptime: 0.268496 0.000962 0.269458 ( 0.270865)
|
146
|
+
# re=~: 0.024872 0.000070 0.024942 ( 0.025057)
|
147
|
+
# re.match?: 0.019745 0.000095 0.019840 ( 0.020058)
|
148
|
+
# strptime fail: 0.141309 0.000354 0.141663 ( 0.142266)
|
149
|
+
# re=~ fail: 0.031637 0.000095 0.031732 ( 0.031872)
|
150
|
+
# re.match? fail: 0.011249 0.000056 0.011305 ( 0.011375)
|
151
|
+
# length fail: 0.007177 0.000024 0.007201 ( 0.007222)
|
152
|
+
#
|
153
|
+
# NOTE: The faster Regexp#match? was introduced in Ruby 2.4.0, so we
|
154
|
+
# can't really rely on it being available
|
155
|
+
if //.respond_to?(:match?)
|
156
|
+
def quick_check_timestamp(v)
|
157
|
+
v.length == timestamp_fm_format.length && FmRest::V1::fm_date_to_regexp(timestamp_fm_format).match?(v)
|
158
|
+
end
|
159
|
+
|
160
|
+
def quick_check_date(v)
|
161
|
+
v.length == date_fm_format.length && FmRest::V1::fm_date_to_regexp(date_fm_format).match?(v)
|
162
|
+
end
|
163
|
+
|
164
|
+
def quick_check_time(v)
|
165
|
+
v.length == time_fm_format.length && FmRest::V1::fm_date_to_regexp(time_fm_format).match?(v)
|
166
|
+
end
|
167
|
+
else
|
168
|
+
def quick_check_timestamp(v)
|
169
|
+
v.length == timestamp_fm_format.length && FmRest::V1::fm_date_to_regexp(timestamp_fm_format) =~ v
|
170
|
+
end
|
171
|
+
|
172
|
+
def quick_check_date(v)
|
173
|
+
v.length == date_fm_format.length && FmRest::V1::fm_date_to_regexp(date_fm_format) =~ v
|
174
|
+
end
|
175
|
+
|
176
|
+
def quick_check_time(v)
|
177
|
+
v.length == time_fm_format.length && FmRest::V1::fm_date_to_regexp(time_fm_format) =~ v
|
178
|
+
end
|
103
179
|
end
|
104
180
|
|
105
|
-
def
|
106
|
-
@
|
107
|
-
"%Y/%m/%d " + FmRest::V1.convert_date_time_format(@options[:time_format] || DEFAULT_TIME_FORMAT)
|
181
|
+
def local_timezone?
|
182
|
+
@local_timezone ||= @settings.timezone.try(:to_sym) == :local
|
108
183
|
end
|
109
184
|
|
110
185
|
def coerce_dates
|
111
|
-
@
|
186
|
+
@settings.coerce_dates
|
112
187
|
end
|
113
188
|
|
114
189
|
alias_method :enabled?, :coerce_dates
|
data/lib/fmrest/v1/utils.rb
CHANGED
@@ -5,17 +5,6 @@ module FmRest
|
|
5
5
|
module Utils
|
6
6
|
VALID_SCRIPT_KEYS = [:prerequest, :presort, :after].freeze
|
7
7
|
|
8
|
-
FM_DATETIME_FORMAT_MATCHER = /MM|mm|dd|HH|ss|yyyy/.freeze
|
9
|
-
|
10
|
-
FM_DATETIME_FORMAT_SUBSTITUTIONS = {
|
11
|
-
"MM" => "%m",
|
12
|
-
"dd" => "%d",
|
13
|
-
"yyyy" => "%Y",
|
14
|
-
"HH" => "%H",
|
15
|
-
"mm" => "%M",
|
16
|
-
"ss" => "%S"
|
17
|
-
}.freeze
|
18
|
-
|
19
8
|
# Converts custom script options to a hash with the Data API's expected
|
20
9
|
# JSON script format.
|
21
10
|
#
|
@@ -83,12 +72,6 @@ module FmRest
|
|
83
72
|
params
|
84
73
|
end
|
85
74
|
|
86
|
-
# Converts a FM date-time format to `Date.strptime` format
|
87
|
-
#
|
88
|
-
def convert_date_time_format(fm_format)
|
89
|
-
fm_format.gsub(FM_DATETIME_FORMAT_MATCHER, FM_DATETIME_FORMAT_SUBSTITUTIONS)
|
90
|
-
end
|
91
|
-
|
92
75
|
private
|
93
76
|
|
94
77
|
def convert_script_arguments(script_arguments, suffix = nil)
|
data/lib/fmrest/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fmrest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pedro Carbajal
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -54,30 +54,30 @@ dependencies:
|
|
54
54
|
name: bundler
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
56
56
|
requirements:
|
57
|
-
- - "
|
57
|
+
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version: '
|
59
|
+
version: '0'
|
60
60
|
type: :development
|
61
61
|
prerelease: false
|
62
62
|
version_requirements: !ruby/object:Gem::Requirement
|
63
63
|
requirements:
|
64
|
-
- - "
|
64
|
+
- - ">="
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version: '
|
66
|
+
version: '0'
|
67
67
|
- !ruby/object:Gem::Dependency
|
68
68
|
name: rake
|
69
69
|
requirement: !ruby/object:Gem::Requirement
|
70
70
|
requirements:
|
71
|
-
- - "
|
71
|
+
- - ">="
|
72
72
|
- !ruby/object:Gem::Version
|
73
|
-
version: '
|
73
|
+
version: '0'
|
74
74
|
type: :development
|
75
75
|
prerelease: false
|
76
76
|
version_requirements: !ruby/object:Gem::Requirement
|
77
77
|
requirements:
|
78
|
-
- - "
|
78
|
+
- - ">="
|
79
79
|
- !ruby/object:Gem::Version
|
80
|
-
version: '
|
80
|
+
version: '0'
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
82
|
name: rspec
|
83
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,14 +98,14 @@ dependencies:
|
|
98
98
|
requirements:
|
99
99
|
- - ">="
|
100
100
|
- !ruby/object:Gem::Version
|
101
|
-
version:
|
101
|
+
version: 5.3.3
|
102
102
|
type: :development
|
103
103
|
prerelease: false
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
105
|
requirements:
|
106
106
|
- - ">="
|
107
107
|
- !ruby/object:Gem::Version
|
108
|
-
version:
|
108
|
+
version: 5.3.3
|
109
109
|
- !ruby/object:Gem::Dependency
|
110
110
|
name: webmock
|
111
111
|
requirement: !ruby/object:Gem::Requirement
|
@@ -152,16 +152,16 @@ dependencies:
|
|
152
152
|
name: sqlite3
|
153
153
|
requirement: !ruby/object:Gem::Requirement
|
154
154
|
requirements:
|
155
|
-
- - "
|
155
|
+
- - "~>"
|
156
156
|
- !ruby/object:Gem::Version
|
157
|
-
version:
|
157
|
+
version: 1.4.0
|
158
158
|
type: :development
|
159
159
|
prerelease: false
|
160
160
|
version_requirements: !ruby/object:Gem::Requirement
|
161
161
|
requirements:
|
162
|
-
- - "
|
162
|
+
- - "~>"
|
163
163
|
- !ruby/object:Gem::Version
|
164
|
-
version:
|
164
|
+
version: 1.4.0
|
165
165
|
- !ruby/object:Gem::Dependency
|
166
166
|
name: mock_redis
|
167
167
|
requirement: !ruby/object:Gem::Requirement
|
@@ -235,8 +235,10 @@ files:
|
|
235
235
|
- LICENSE.txt
|
236
236
|
- README.md
|
237
237
|
- Rakefile
|
238
|
+
- UPGRADING
|
238
239
|
- fmrest.gemspec
|
239
240
|
- lib/fmrest.rb
|
241
|
+
- lib/fmrest/connection_settings.rb
|
240
242
|
- lib/fmrest/errors.rb
|
241
243
|
- lib/fmrest/spyke.rb
|
242
244
|
- lib/fmrest/spyke/base.rb
|
@@ -250,6 +252,7 @@ files:
|
|
250
252
|
- lib/fmrest/spyke/model/global_fields.rb
|
251
253
|
- lib/fmrest/spyke/model/http.rb
|
252
254
|
- lib/fmrest/spyke/model/orm.rb
|
255
|
+
- lib/fmrest/spyke/model/record_id.rb
|
253
256
|
- lib/fmrest/spyke/model/serialization.rb
|
254
257
|
- lib/fmrest/spyke/model/uri.rb
|
255
258
|
- lib/fmrest/spyke/portal.rb
|
@@ -262,10 +265,13 @@ files:
|
|
262
265
|
- lib/fmrest/token_store/base.rb
|
263
266
|
- lib/fmrest/token_store/memory.rb
|
264
267
|
- lib/fmrest/token_store/moneta.rb
|
268
|
+
- lib/fmrest/token_store/null.rb
|
265
269
|
- lib/fmrest/token_store/redis.rb
|
266
270
|
- lib/fmrest/v1.rb
|
271
|
+
- lib/fmrest/v1/auth.rb
|
267
272
|
- lib/fmrest/v1/connection.rb
|
268
273
|
- lib/fmrest/v1/container_fields.rb
|
274
|
+
- lib/fmrest/v1/dates.rb
|
269
275
|
- lib/fmrest/v1/paths.rb
|
270
276
|
- lib/fmrest/v1/raise_errors.rb
|
271
277
|
- lib/fmrest/v1/token_session.rb
|
@@ -278,7 +284,22 @@ homepage: https://github.com/beezwax/fmrest-ruby
|
|
278
284
|
licenses:
|
279
285
|
- MIT
|
280
286
|
metadata: {}
|
281
|
-
post_install_message:
|
287
|
+
post_install_message: |+
|
288
|
+
=======================================
|
289
|
+
Notes on upgrading from fmrest < 0.12
|
290
|
+
=======================================
|
291
|
+
|
292
|
+
There's a small breaking change in fmrest 0.12 that will most likely not affect
|
293
|
+
you, but you may want to be aware of:
|
294
|
+
|
295
|
+
Previous to this version the record ID on an FmRest::Spyke::Base instance could
|
296
|
+
be set with `id=`. This caused problems in cases where a FileMaker layout had a
|
297
|
+
field named `id`, so `id=` got renamed to `__record_id=`. Setting the record ID
|
298
|
+
by hand however isn't something useful or that should be done at all, so it's
|
299
|
+
very unlikely that this change will affect your existing code at all.
|
300
|
+
|
301
|
+
Thanks for using fmrest-ruby!
|
302
|
+
|
282
303
|
rdoc_options: []
|
283
304
|
require_paths:
|
284
305
|
- lib
|
@@ -294,7 +315,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
294
315
|
version: '0'
|
295
316
|
requirements: []
|
296
317
|
rubygems_version: 3.0.6
|
297
|
-
signing_key:
|
318
|
+
signing_key:
|
298
319
|
specification_version: 4
|
299
320
|
summary: FileMaker Data API client using Faraday
|
300
321
|
test_files: []
|
322
|
+
...
|