fmrest-core 0.13.0 → 0.15.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +1 -0
- data/CHANGELOG.md +20 -0
- data/README.md +116 -81
- data/lib/fmrest.rb +14 -0
- data/lib/fmrest/v1/container_fields.rb +15 -10
- data/lib/fmrest/v1/dates.rb +38 -2
- data/lib/fmrest/v1/utils.rb +13 -0
- data/lib/fmrest/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 01ec00e52b9c84c094188e3b9b4e3f869063294ebf695364b9141dbce28a2e7c
|
4
|
+
data.tar.gz: 00b228812583d4b256e0c2f9be8336db9d47b14fd2e1324ecdf6012c91af3c6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cadaee1025630ff4e0e2110bc9d294262861a9baa578b84e88fca0c7ed15e8a73edba710232d535197f0c74cd0bb2af8758998710876f1ead48532bb0f69c27e
|
7
|
+
data.tar.gz: 15e8c19893fc459e29f924352b1657dadfadc242201811719b1a2e871106af7616c99ab4f8adfd76f775021b288002c6d98d04ba64f30b549eb3802618e23b34
|
data/.yardopts
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
## Changelog
|
2
2
|
|
3
|
+
### 0.15.2
|
4
|
+
|
5
|
+
* Fix autoloading of `FmRest::Layout`
|
6
|
+
|
7
|
+
### 0.15.0
|
8
|
+
|
9
|
+
* Much improved querying API (see documentation on querying), adding new
|
10
|
+
`.query` capabilities, as well as two new methods: `.match` and `.or`
|
11
|
+
|
12
|
+
### 0.14.0
|
13
|
+
|
14
|
+
* Aliased `FmRest::Spyke::Base` as `FmRest::Layout` (now preferred), and
|
15
|
+
provided a shortcut version for setting the layout name (e.g. `class Foo <
|
16
|
+
FmRest::Layout("LayoutName")`)
|
17
|
+
* Made `layout` class setting subclass-inheritable
|
18
|
+
|
19
|
+
### 0.13.1
|
20
|
+
|
21
|
+
* Fix downloading of container field data from FMS19+
|
22
|
+
|
3
23
|
### 0.13.0
|
4
24
|
|
5
25
|
* Split `fmrest` gem into `fmrest-core` and `fmrest-spyke`. `fmrest` becomes a
|
data/README.md
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/fmrest.svg?style=flat)](https://rubygems.org/gems/fmrest)
|
4
4
|
![CI](https://github.com/beezwax/fmrest-ruby/workflows/CI/badge.svg)
|
5
|
+
[![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](https://rubydoc.info/github/beezwax/fmrest-ruby)
|
5
6
|
|
6
7
|
A Ruby client for
|
7
8
|
[FileMaker 18 and 19's Data API](https://help.claris.com/en/data-api-guide)
|
@@ -9,7 +10,7 @@ using
|
|
9
10
|
[Faraday](https://github.com/lostisland/faraday) and with optional
|
10
11
|
ActiveRecord-ish ORM features through [Spyke](https://github.com/balvig/spyke).
|
11
12
|
|
12
|
-
fmrest-ruby only partially implements FileMaker
|
13
|
+
fmrest-ruby only partially implements FileMaker 19's Data API.
|
13
14
|
See the [implementation completeness table](#api-implementation-completeness-table)
|
14
15
|
to see if a feature you need is natively supported by the gem.
|
15
16
|
|
@@ -17,10 +18,10 @@ to see if a feature you need is natively supported by the gem.
|
|
17
18
|
|
18
19
|
The `fmrest` gem is a wrapper for two other gems:
|
19
20
|
|
20
|
-
* `fmrest-
|
21
|
+
* `fmrest-spyke`, providing an ActiveRecord-like ORM library built on top
|
22
|
+
of `fmrest-core` and [Spyke](https://github.com/balvig/spyke).
|
23
|
+
* `fmrest-core`, providing the core Faraday connection builder, session
|
21
24
|
management, and other core utilities.
|
22
|
-
* `fmrest-spyke`, which provides an ActiveRecord-like ORM library built on top
|
23
|
-
of `fmrest-core` and Spyke.
|
24
25
|
|
25
26
|
## Installation
|
26
27
|
|
@@ -30,7 +31,7 @@ Add this to your Gemfile:
|
|
30
31
|
gem 'fmrest'
|
31
32
|
```
|
32
33
|
|
33
|
-
Or if you just want to use the Faraday connection without the ORM features
|
34
|
+
Or if you just want to use the Faraday connection without the ORM features:
|
34
35
|
|
35
36
|
```ruby
|
36
37
|
gem 'fmrest-core'
|
@@ -40,10 +41,11 @@ gem 'fmrest-core'
|
|
40
41
|
|
41
42
|
### ORM example
|
42
43
|
|
43
|
-
Most people would want to use the ORM features
|
44
|
+
Most people would want to use the ORM features:
|
44
45
|
|
45
46
|
```ruby
|
46
|
-
|
47
|
+
# A Layout model connecting to the "Honeybees Web" FileMaker layout
|
48
|
+
class Honeybee < FmRest::Layout("Honeybees Web")
|
47
49
|
# Connection settings
|
48
50
|
self.fmrest_config = {
|
49
51
|
host: "…",
|
@@ -53,13 +55,28 @@ class Honeybee < FmRest::Spyke::Base
|
|
53
55
|
}
|
54
56
|
|
55
57
|
# Mapped attributes
|
56
|
-
attributes name: "Bee Name", age: "Bee Age"
|
58
|
+
attributes name: "Bee Name", age: "Bee Age", created_on: "Created On"
|
57
59
|
|
58
|
-
#
|
59
|
-
has_portal :
|
60
|
+
# Portal associations
|
61
|
+
has_portal :tasks
|
60
62
|
|
61
|
-
# File
|
63
|
+
# File containers
|
62
64
|
container :photo, field_name: "Bee Photo"
|
65
|
+
|
66
|
+
# Scopes
|
67
|
+
scope :can_legally_fly, -> { query(age: ">18") }
|
68
|
+
|
69
|
+
# Client-side validations
|
70
|
+
validates :name, presence: true
|
71
|
+
|
72
|
+
# Callbacks
|
73
|
+
before_save :set_created_on
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def set_created_on
|
78
|
+
self.created_on = Date.today
|
79
|
+
end
|
63
80
|
end
|
64
81
|
|
65
82
|
# Find a record by id
|
@@ -68,7 +85,7 @@ bee = Honeybee.find(9)
|
|
68
85
|
bee.name = "Hutch"
|
69
86
|
|
70
87
|
# Add a new record to portal
|
71
|
-
bee.
|
88
|
+
bee.tasks.build(urgency: "Today")
|
72
89
|
|
73
90
|
bee.save
|
74
91
|
```
|
@@ -88,11 +105,11 @@ connection = FmRest::V1.build_connection(
|
|
88
105
|
)
|
89
106
|
|
90
107
|
# Get all records (as parsed JSON)
|
91
|
-
connection.get("layouts/
|
108
|
+
connection.get("layouts/FancyLayout/records")
|
92
109
|
|
93
110
|
# Create new record
|
94
111
|
connection.post do |req|
|
95
|
-
req.url "layouts/
|
112
|
+
req.url "layouts/FancyLayout/records"
|
96
113
|
|
97
114
|
# You can just pass a hash for the JSON body
|
98
115
|
req.body = { … }
|
@@ -128,9 +145,9 @@ You can also pass a `:log` option for basic request logging, see the section on
|
|
128
145
|
Option | Description | Format | Default
|
129
146
|
--------------------|--------------------------------------------|-----------------------------|--------
|
130
147
|
`:host` | Hostname with optional port, e.g. `"example.com:9000"` | String | None
|
131
|
-
`:database` |
|
132
|
-
`:username` |
|
133
|
-
`:password` |
|
148
|
+
`:database` | The name of the database to connect to | String | None
|
149
|
+
`:username` | A Data API-ready account | String | None
|
150
|
+
`:password` | Your password | String | None
|
134
151
|
`:account_name` | Alias of `:username` | String | None
|
135
152
|
`:ssl` | SSL options to be forwarded to Faraday | Faraday SSL options | None
|
136
153
|
`:proxy` | Proxy options to be forwarded to Faraday | Faraday proxy options | None
|
@@ -157,8 +174,8 @@ FmRest.default_connection_settings = {
|
|
157
174
|
}
|
158
175
|
```
|
159
176
|
|
160
|
-
These settings will be used by default by `FmRest::
|
161
|
-
|
177
|
+
These settings will be used by default by `FmRest::Layout` models whenever you
|
178
|
+
don't set `fmrest_config=` explicitly, as well as by
|
162
179
|
`FmRest::V1.build_connection` in case you're setting up your Faraday connection
|
163
180
|
manually.
|
164
181
|
|
@@ -188,11 +205,11 @@ building REST ORM models. fmrest-ruby builds its ORM features atop Spyke,
|
|
188
205
|
bundled in the `fmrest-spyke` gem (already included if you're using the
|
189
206
|
`fmrest` gem).
|
190
207
|
|
191
|
-
To create a model you can inherit directly from `FmRest::
|
192
|
-
|
208
|
+
To create a model you can inherit directly from `FmRest::Layout` (itself a
|
209
|
+
subclass of `Spyke::Base`).
|
193
210
|
|
194
211
|
```ruby
|
195
|
-
class Honeybee < FmRest::
|
212
|
+
class Honeybee < FmRest::Layout
|
196
213
|
end
|
197
214
|
```
|
198
215
|
|
@@ -216,17 +233,23 @@ bee = Honeybee.find(9) # GET request
|
|
216
233
|
|
217
234
|
It's recommended that you read Spyke's documentation for more information on
|
218
235
|
these basic features. If you've used ActiveRecord or similar ORM libraries
|
219
|
-
|
236
|
+
you'll find it quite familiar.
|
220
237
|
|
221
|
-
|
238
|
+
Notice that `FmRest::Layout` is aliased as `FmRest::Spyke::Base`. Previous
|
239
|
+
versions of fmrest-ruby only provided the latter version, so if you're already
|
240
|
+
using `FmRest::Spyke::Base` there's no need to rename your classes to
|
241
|
+
`FmRest::Layout`, both will continue to work interchangeably.
|
242
|
+
|
243
|
+
In addition, `FmRest::Layout` extends `Spyke::Base` with the following
|
222
244
|
features:
|
223
245
|
|
224
|
-
###
|
246
|
+
### FmRest::Layout.fmrest_config=
|
225
247
|
|
226
|
-
This allows you to set
|
248
|
+
This allows you to set Data API connection settings specific to your model
|
249
|
+
class:
|
227
250
|
|
228
251
|
```ruby
|
229
|
-
class Honeybee < FmRest::
|
252
|
+
class Honeybee < FmRest::Layout
|
230
253
|
self.fmrest_config = {
|
231
254
|
host: "…",
|
232
255
|
database: "…",
|
@@ -244,9 +267,8 @@ does the initial connection setup and then inherit from it in models using that
|
|
244
267
|
same connection. E.g.:
|
245
268
|
|
246
269
|
```ruby
|
247
|
-
class BeeBase < FmRest::
|
248
|
-
self.fmrest_config = { host: "…", … }
|
249
|
-
}
|
270
|
+
class BeeBase < FmRest::Layout
|
271
|
+
self.fmrest_config = { host: "…", database: "…", … }
|
250
272
|
end
|
251
273
|
|
252
274
|
class Honeybee < BeeBase
|
@@ -254,34 +276,46 @@ class Honeybee < BeeBase
|
|
254
276
|
end
|
255
277
|
```
|
256
278
|
|
279
|
+
Also, if not set, your model will try to use
|
280
|
+
`FmRest.default_connection_settings` instead.
|
281
|
+
|
257
282
|
#### Connection settings overlays
|
258
283
|
|
259
284
|
There may be cases where you want to use a different set of connection settings
|
260
285
|
depending on context. For example, if you want to use username and password
|
261
|
-
provided by the user in a web application. Since
|
262
|
-
at the class level, changing the username/password for the model in one
|
263
|
-
would also change it in all other contexts, leading to security issues.
|
286
|
+
provided by the user in a web application. Since `.fmrest_config`
|
287
|
+
is set at the class level, changing the username/password for the model in one
|
288
|
+
context would also change it in all other contexts, leading to security issues.
|
264
289
|
|
265
290
|
To solve this scenario, fmrest-ruby provides a way of defining thread-local and
|
266
|
-
reversible connection settings overlays through
|
291
|
+
reversible connection settings overlays through
|
292
|
+
`.fmrest_config_overlay=`.
|
267
293
|
|
268
294
|
See the [main document on connection setting overlays](docs/ConfigOverlays.md)
|
269
295
|
for details on how it works.
|
270
296
|
|
271
|
-
###
|
297
|
+
### FmRest::Layout.layout
|
272
298
|
|
273
|
-
Use `
|
299
|
+
Use `layout` to set the layout name for your model.
|
274
300
|
|
275
301
|
```ruby
|
276
|
-
class Honeybee < FmRest::
|
302
|
+
class Honeybee < FmRest::Layout
|
277
303
|
layout "Honeybees Web"
|
278
304
|
end
|
279
305
|
```
|
280
306
|
|
281
|
-
|
282
|
-
the layout
|
307
|
+
Alternatively, if you're inheriting from `FmRest::Layout` directly you can set
|
308
|
+
the layout name in the class definition line:
|
309
|
+
|
310
|
+
```ruby
|
311
|
+
class Honeybee < FmRest::Layout("Honeybees Web")
|
312
|
+
```
|
313
|
+
|
314
|
+
Note that you only need to manually set the layout name if the name of the
|
315
|
+
class and the name of the layout differ, otherwise fmrest-ruby will just use
|
316
|
+
the name of the class.
|
283
317
|
|
284
|
-
###
|
318
|
+
### FmRest::Layout.request_auth_token
|
285
319
|
|
286
320
|
Requests a Data API session token using the connection settings in
|
287
321
|
`fmrest_config` and returns it if successful, otherwise returns `false`.
|
@@ -290,16 +324,16 @@ You normally don't need to use this method as fmrest-ruby will automatically
|
|
290
324
|
request and store session tokens for you (provided that `:autologin` is
|
291
325
|
`true`).
|
292
326
|
|
293
|
-
###
|
327
|
+
### FmRest::Layout.logout
|
294
328
|
|
295
|
-
Use
|
329
|
+
Use `.logout` to log out from the database session (you may call it on any
|
296
330
|
model that uses the database session you want to log out from).
|
297
331
|
|
298
332
|
```ruby
|
299
333
|
Honeybee.logout
|
300
334
|
```
|
301
335
|
|
302
|
-
### Mapped
|
336
|
+
### Mapped FmRest::Layout.attributes
|
303
337
|
|
304
338
|
Spyke allows you to define your model's attributes using `attributes`, however
|
305
339
|
sometimes FileMaker's field names aren't very Ruby-ORM-friendly, especially
|
@@ -308,7 +342,7 @@ fmrest-ruby extends `attributes`' functionality to allow you to map
|
|
308
342
|
Ruby-friendly attribute names to FileMaker field names. E.g.:
|
309
343
|
|
310
344
|
```ruby
|
311
|
-
class Honeybee < FmRest::
|
345
|
+
class Honeybee < FmRest::Layout
|
312
346
|
attributes first_name: "First Name", last_name: "Last Name"
|
313
347
|
end
|
314
348
|
```
|
@@ -327,16 +361,16 @@ bee.first_name = "Queen"
|
|
327
361
|
bee.attributes # => { "First Name": "Queen", "Last Name": "Buzz" }
|
328
362
|
```
|
329
363
|
|
330
|
-
###
|
364
|
+
### FmRest::Layout.has_portal
|
331
365
|
|
332
366
|
You can define portal associations on your model wth `has_portal`, as such:
|
333
367
|
|
334
368
|
```ruby
|
335
|
-
class Honeybee < FmRest::
|
369
|
+
class Honeybee < FmRest::Layout
|
336
370
|
has_portal :flowers
|
337
371
|
end
|
338
372
|
|
339
|
-
class Flower < FmRest::
|
373
|
+
class Flower < FmRest::Layout
|
340
374
|
attributes :color, :species
|
341
375
|
end
|
342
376
|
```
|
@@ -371,8 +405,8 @@ Guides](https://guides.rubyonrails.org/active_model_basics.html#dirty).
|
|
371
405
|
Since Spyke is API-agnostic it only provides a wide-purpose `.where` method for
|
372
406
|
passing arbitrary parameters to the REST backend. fmrest-ruby however is well
|
373
407
|
aware of its backend API, so it extends Spkye models with a bunch of useful
|
374
|
-
querying methods: `.query`, `.
|
375
|
-
etc.
|
408
|
+
querying methods: `.query`, `.match`, `.omit`, `.limit`, `.offset`, `.sort`,
|
409
|
+
`.portal`, `.script`, etc.
|
376
410
|
|
377
411
|
See the [main document on querying](docs/Querying.md) for detailed information
|
378
412
|
on the query API methods.
|
@@ -393,7 +427,7 @@ detailed information on how those work.
|
|
393
427
|
You can define container fields on your model class with `container`:
|
394
428
|
|
395
429
|
```ruby
|
396
|
-
class Honeybee < FmRest::
|
430
|
+
class Honeybee < FmRest::Layout
|
397
431
|
container :photo, field_name: "Beehive Photo ID"
|
398
432
|
end
|
399
433
|
```
|
@@ -411,7 +445,7 @@ details.
|
|
411
445
|
|
412
446
|
### Setting global field values
|
413
447
|
|
414
|
-
You can call `.set_globals` on any `FmRest::
|
448
|
+
You can call `.set_globals` on any `FmRest::Layout` model to set global
|
415
449
|
field values on the database that model is configured for.
|
416
450
|
|
417
451
|
See the [main document on setting global field values](docs/GlobalFields.md)
|
@@ -435,7 +469,7 @@ FmRest.default_connection_settings = {
|
|
435
469
|
}
|
436
470
|
|
437
471
|
# Or in your model
|
438
|
-
class LoggyBee < FmRest::
|
472
|
+
class LoggyBee < FmRest::Layout
|
439
473
|
self.fmrest_config = {
|
440
474
|
host: "…",
|
441
475
|
…
|
@@ -449,7 +483,7 @@ If you need to set up more complex logging for your models can use the
|
|
449
483
|
Faraday connection, e.g.:
|
450
484
|
|
451
485
|
```ruby
|
452
|
-
class LoggyBee < FmRest::
|
486
|
+
class LoggyBee < FmRest::Layout
|
453
487
|
faraday do |conn|
|
454
488
|
conn.response :logger, MyApp.logger, bodies: true
|
455
489
|
end
|
@@ -460,31 +494,31 @@ end
|
|
460
494
|
|
461
495
|
FM Data API reference: https://fmhelp.filemaker.com/docs/18/en/dataapi/
|
462
496
|
|
463
|
-
| FM 18 Data API feature | Supported by basic connection | Supported by FmRest::
|
464
|
-
|
465
|
-
| Log in using HTTP Basic Auth | Yes | Yes
|
466
|
-
| Log in using OAuth | No | No
|
467
|
-
| Log in to an external data source | No | No
|
468
|
-
| Log in using a FileMaker ID account | No | No
|
469
|
-
| Log out | Yes | Yes
|
470
|
-
| Get product information | Manual* | No
|
471
|
-
| Get database names | Manual* | No
|
472
|
-
| Get script names | Manual* | No
|
473
|
-
| Get layout names | Manual* | No
|
474
|
-
| Get layout metadata | Manual* | No
|
475
|
-
| Create a record | Manual* | Yes
|
476
|
-
| Edit a record | Manual* | Yes
|
477
|
-
| Duplicate a record | Manual* | No
|
478
|
-
| Delete a record | Manual* | Yes
|
479
|
-
| Edit portal records | Manual* | Yes
|
480
|
-
| Get a single record | Manual* | Yes
|
481
|
-
| Get a range of records | Manual* | Yes
|
482
|
-
| Get container data | Manual* | Yes
|
483
|
-
| Upload container data | Manual* | Yes
|
484
|
-
| Perform a find request | Manual* | Yes
|
485
|
-
| Set global field values | Manual* | Yes
|
486
|
-
| Run a script | Manual* | Yes
|
487
|
-
| Run a script with another request | Manual* | Yes
|
497
|
+
| FM 18 Data API feature | Supported by basic connection | Supported by FmRest::Layout |
|
498
|
+
|-------------------------------------|-------------------------------|-----------------------------|
|
499
|
+
| Log in using HTTP Basic Auth | Yes | Yes |
|
500
|
+
| Log in using OAuth | No | No |
|
501
|
+
| Log in to an external data source | No | No |
|
502
|
+
| Log in using a FileMaker ID account | No | No |
|
503
|
+
| Log out | Yes | Yes |
|
504
|
+
| Get product information | Manual* | No |
|
505
|
+
| Get database names | Manual* | No |
|
506
|
+
| Get script names | Manual* | No |
|
507
|
+
| Get layout names | Manual* | No |
|
508
|
+
| Get layout metadata | Manual* | No |
|
509
|
+
| Create a record | Manual* | Yes |
|
510
|
+
| Edit a record | Manual* | Yes |
|
511
|
+
| Duplicate a record | Manual* | No |
|
512
|
+
| Delete a record | Manual* | Yes |
|
513
|
+
| Edit portal records | Manual* | Yes |
|
514
|
+
| Get a single record | Manual* | Yes |
|
515
|
+
| Get a range of records | Manual* | Yes |
|
516
|
+
| Get container data | Manual* | Yes |
|
517
|
+
| Upload container data | Manual* | Yes |
|
518
|
+
| Perform a find request | Manual* | Yes |
|
519
|
+
| Set global field values | Manual* | Yes |
|
520
|
+
| Run a script | Manual* | Yes |
|
521
|
+
| Run a script with another request | Manual* | Yes |
|
488
522
|
|
489
523
|
\* You can manually supply the URL and JSON to a `FmRest` connection.
|
490
524
|
|
@@ -496,6 +530,7 @@ the following Ruby implementations:
|
|
496
530
|
* Ruby 2.5
|
497
531
|
* Ruby 2.6
|
498
532
|
* Ruby 2.7
|
533
|
+
* Ruby 3.0
|
499
534
|
|
500
535
|
## Gem development
|
501
536
|
|
@@ -518,6 +553,6 @@ See [LICENSE.txt](LICENSE.txt).
|
|
518
553
|
|
519
554
|
## Disclaimer
|
520
555
|
|
521
|
-
This project is not sponsored by or otherwise affiliated with
|
522
|
-
an Apple subsidiary. FileMaker is a trademark of
|
523
|
-
the U.S. and other countries.
|
556
|
+
This project is not sponsored by or otherwise affiliated with Claris
|
557
|
+
International Inc., an Apple Inc. subsidiary. FileMaker is a trademark of
|
558
|
+
Claris International Inc., registered in the U.S. and other countries.
|
data/lib/fmrest.rb
CHANGED
@@ -11,6 +11,7 @@ module FmRest
|
|
11
11
|
autoload :V1, "fmrest/v1"
|
12
12
|
autoload :TokenStore, "fmrest/token_store"
|
13
13
|
autoload :Spyke, "fmrest/spyke"
|
14
|
+
autoload :Layout, "fmrest/spyke"
|
14
15
|
|
15
16
|
class << self
|
16
17
|
attr_accessor :token_store
|
@@ -32,5 +33,18 @@ module FmRest
|
|
32
33
|
warn "[DEPRECATION] `FmRest.config` is deprecated, use `FmRest.default_connection_settings` instead"
|
33
34
|
default_connection_settings
|
34
35
|
end
|
36
|
+
|
37
|
+
# Shortcut for FmRest::V1.escape_find_operators
|
38
|
+
#
|
39
|
+
# @param (see FmRest::V1.escape_find_operators
|
40
|
+
# @return (see FmRest::V1.escape_find_operators
|
41
|
+
def e(s)
|
42
|
+
V1.escape_find_operators(s)
|
43
|
+
end
|
44
|
+
|
45
|
+
def Layout(*_)
|
46
|
+
require "fmrest/spyke"
|
47
|
+
self.Layout(*_)
|
48
|
+
end
|
35
49
|
end
|
36
50
|
end
|
@@ -45,18 +45,23 @@ module FmRest
|
|
45
45
|
proxy: proxy_options || FmRest.default_connection_settings[:proxy]
|
46
46
|
)
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
cookie_response = conn.get url
|
48
|
+
openuri_options =
|
49
|
+
faraday_connection_to_openuri_options(conn).merge(redirect: false)
|
51
50
|
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
begin
|
52
|
+
url.open(openuri_options)
|
53
|
+
rescue OpenURI::HTTPRedirect => e
|
54
|
+
unless cookie = e.io.metas.dig("set-cookie", 0)
|
55
|
+
raise FmRest::ContainerFieldError, "Container field's initial request didn't return a session cookie, the URL may be stale (try downloading it again immediately after retrieving the record)"
|
56
|
+
end
|
55
57
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
58
|
+
url = URI(e.io.meta["location"])
|
59
|
+
|
60
|
+
# Now request the URL again with the proper session cookie using
|
61
|
+
# OpenURI, which wraps the response in an IO object which also responds
|
62
|
+
# to #content_type
|
63
|
+
url.open(openuri_options.merge("Cookie" => cookie))
|
64
|
+
end
|
60
65
|
end
|
61
66
|
|
62
67
|
# Handles the core logic of uploading a file into a container field
|
data/lib/fmrest/v1/dates.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
module FmRest
|
4
4
|
module V1
|
5
5
|
module Dates
|
6
|
+
FM_DATE_FORMAT = "%m/%d/%Y"
|
7
|
+
FM_DATETIME_FORMAT = "#{FM_DATE_FORMAT} %H:%M:%S"
|
6
8
|
FM_DATETIME_FORMAT_MATCHER = /MM|mm|dd|HH|ss|yyyy/.freeze
|
7
9
|
|
8
10
|
FM_DATE_TO_STRPTIME_SUBSTITUTIONS = {
|
@@ -55,8 +57,8 @@ module FmRest
|
|
55
57
|
# Takes a DateTime dt, and returns the correct local offset for that dt,
|
56
58
|
# daylight savings included, in fraction of a day.
|
57
59
|
#
|
58
|
-
# By default, if ActiveSupport's Time.zone is set it will be used
|
59
|
-
# of the system timezone.
|
60
|
+
# By default, if ActiveSupport's `Time.zone` is set it will be used
|
61
|
+
# instead of the system timezone.
|
60
62
|
#
|
61
63
|
# @param dt [DateTime] The DateTime to get the offset for
|
62
64
|
# @param zone [nil, String, TimeZone] The timezone to use to calculate
|
@@ -76,6 +78,40 @@ module FmRest
|
|
76
78
|
|
77
79
|
Rational(time.utc_offset, 86400) # seconds in one day (24*60*60)
|
78
80
|
end
|
81
|
+
|
82
|
+
# Returns a list of all datetime classes recognized by fmrest-ruby,
|
83
|
+
# including `FmRest::StringDateTime` if defined. Useful for using in a
|
84
|
+
# `case .. when` statement.
|
85
|
+
#
|
86
|
+
def datetime_classes
|
87
|
+
[DateTime, Time, defined?(FmRest::StringDateTime) && FmRest::StringDateTime].compact.freeze
|
88
|
+
end
|
89
|
+
|
90
|
+
# Returns a list of all date classes recognized by fmrest-ruby, including
|
91
|
+
# `FmRest::StringDate` if defined. Useful for using in a `case .. when`
|
92
|
+
# statement.
|
93
|
+
#
|
94
|
+
def date_classes
|
95
|
+
[Date, defined?(FmRest::StringDate) && FmRest::StringDate].compact.freeze
|
96
|
+
end
|
97
|
+
|
98
|
+
# Converts the given DateTime dt to the specified timezone setting offset,
|
99
|
+
# leaving everything else intact.
|
100
|
+
#
|
101
|
+
# @param dt [DateTime] The datetime to convert
|
102
|
+
# @param timezone [nil, Symbol, String] Accepted values are `:utc`,
|
103
|
+
# `:local`, or `nil` (in which case it leaves the given datetime intact)
|
104
|
+
# @return [DateTime] A new datetime with converted timezone
|
105
|
+
def convert_datetime_timezone(dt, timezone)
|
106
|
+
case timezone
|
107
|
+
when :utc, "utc"
|
108
|
+
dt.new_offset(0)
|
109
|
+
when :local, "local"
|
110
|
+
dt.new_offset(FmRest::V1.local_offset_for_datetime(dt))
|
111
|
+
when nil
|
112
|
+
dt
|
113
|
+
end
|
114
|
+
end
|
79
115
|
end
|
80
116
|
end
|
81
117
|
end
|
data/lib/fmrest/v1/utils.rb
CHANGED
@@ -5,6 +5,9 @@ module FmRest
|
|
5
5
|
module Utils
|
6
6
|
VALID_SCRIPT_KEYS = [:prerequest, :presort, :after].freeze
|
7
7
|
|
8
|
+
# See https://help.claris.com/en/pro-help/content/finding-text.html
|
9
|
+
FM_FIND_OPERATORS_RE = /([@\*#\?!=<>"])/
|
10
|
+
|
8
11
|
# Converts custom script options to a hash with the Data API's expected
|
9
12
|
# JSON script format.
|
10
13
|
#
|
@@ -91,6 +94,16 @@ module FmRest
|
|
91
94
|
}
|
92
95
|
end
|
93
96
|
|
97
|
+
# Escapes FileMaker find operators from the given string in order to use
|
98
|
+
# it in a find request.
|
99
|
+
#
|
100
|
+
# @param s [String] The string to escape
|
101
|
+
# @return [String] A new string with find operators escaped with
|
102
|
+
# backslashes
|
103
|
+
def escape_find_operators(s)
|
104
|
+
s.gsub(FM_FIND_OPERATORS_RE, "\\\\\\1")
|
105
|
+
end
|
106
|
+
|
94
107
|
private
|
95
108
|
|
96
109
|
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-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pedro Carbajal
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -108,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
110
|
requirements: []
|
111
|
-
rubygems_version: 3.
|
111
|
+
rubygems_version: 3.0.6
|
112
112
|
signing_key:
|
113
113
|
specification_version: 4
|
114
114
|
summary: FileMaker Data API client using Faraday, core library
|