fmrest 0.7.1 → 0.11.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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +33 -0
- data/CHANGELOG.md +37 -0
- data/README.md +176 -26
- data/fmrest.gemspec +2 -2
- data/lib/fmrest.rb +8 -3
- data/lib/fmrest/connection_settings.rb +124 -0
- data/lib/fmrest/errors.rb +2 -0
- data/lib/fmrest/spyke/base.rb +2 -0
- data/lib/fmrest/spyke/model.rb +2 -0
- data/lib/fmrest/spyke/model/auth.rb +8 -0
- data/lib/fmrest/spyke/model/connection.rb +88 -18
- data/lib/fmrest/spyke/model/global_fields.rb +40 -0
- data/lib/fmrest/spyke/model/orm.rb +2 -1
- data/lib/fmrest/spyke/model/serialization.rb +16 -5
- data/lib/fmrest/spyke/relation.rb +73 -0
- data/lib/fmrest/spyke/spyke_formatter.rb +46 -9
- 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/v1.rb +8 -4
- data/lib/fmrest/v1/auth.rb +30 -0
- data/lib/fmrest/v1/connection.rb +54 -28
- data/lib/fmrest/v1/dates.rb +81 -0
- data/lib/fmrest/v1/raise_errors.rb +3 -1
- data/lib/fmrest/v1/token_session.rb +41 -49
- 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 +18 -13
@@ -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.11.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-09-23 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
|
@@ -226,6 +226,7 @@ executables: []
|
|
226
226
|
extensions: []
|
227
227
|
extra_rdoc_files: []
|
228
228
|
files:
|
229
|
+
- ".github/workflows/ci.yml"
|
229
230
|
- ".gitignore"
|
230
231
|
- ".rspec"
|
231
232
|
- ".travis.yml"
|
@@ -237,6 +238,7 @@ files:
|
|
237
238
|
- Rakefile
|
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
|
@@ -247,6 +249,7 @@ files:
|
|
247
249
|
- lib/fmrest/spyke/model/auth.rb
|
248
250
|
- lib/fmrest/spyke/model/connection.rb
|
249
251
|
- lib/fmrest/spyke/model/container_fields.rb
|
252
|
+
- lib/fmrest/spyke/model/global_fields.rb
|
250
253
|
- lib/fmrest/spyke/model/http.rb
|
251
254
|
- lib/fmrest/spyke/model/orm.rb
|
252
255
|
- lib/fmrest/spyke/model/serialization.rb
|
@@ -263,8 +266,10 @@ files:
|
|
263
266
|
- lib/fmrest/token_store/moneta.rb
|
264
267
|
- lib/fmrest/token_store/redis.rb
|
265
268
|
- lib/fmrest/v1.rb
|
269
|
+
- lib/fmrest/v1/auth.rb
|
266
270
|
- lib/fmrest/v1/connection.rb
|
267
271
|
- lib/fmrest/v1/container_fields.rb
|
272
|
+
- lib/fmrest/v1/dates.rb
|
268
273
|
- lib/fmrest/v1/paths.rb
|
269
274
|
- lib/fmrest/v1/raise_errors.rb
|
270
275
|
- lib/fmrest/v1/token_session.rb
|
@@ -277,7 +282,7 @@ homepage: https://github.com/beezwax/fmrest-ruby
|
|
277
282
|
licenses:
|
278
283
|
- MIT
|
279
284
|
metadata: {}
|
280
|
-
post_install_message:
|
285
|
+
post_install_message:
|
281
286
|
rdoc_options: []
|
282
287
|
require_paths:
|
283
288
|
- lib
|
@@ -293,7 +298,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
293
298
|
version: '0'
|
294
299
|
requirements: []
|
295
300
|
rubygems_version: 3.0.6
|
296
|
-
signing_key:
|
301
|
+
signing_key:
|
297
302
|
specification_version: 4
|
298
303
|
summary: FileMaker Data API client using Faraday
|
299
304
|
test_files: []
|