filemaker 0.0.18 → 0.0.19
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/.rubocop.yml +5 -1
- data/README.md +55 -11
- data/diagram.svg +1 -0
- data/filemaker.gemspec +2 -0
- data/lib/filemaker.rb +2 -1
- data/lib/filemaker/configuration.rb +1 -1
- data/lib/filemaker/layout.rb +1 -1
- data/lib/filemaker/metadata/field.rb +6 -3
- data/lib/filemaker/model/batches.rb +16 -0
- data/lib/filemaker/model/builder.rb +5 -2
- data/lib/filemaker/model/components.rb +2 -0
- data/lib/filemaker/model/criteria.rb +26 -6
- data/lib/filemaker/model/field.rb +11 -2
- data/lib/filemaker/model/fields.rb +15 -9
- data/lib/filemaker/model/optional.rb +1 -1
- data/lib/filemaker/model/pagination.rb +6 -1
- data/lib/filemaker/model/persistable.rb +1 -1
- data/lib/filemaker/model/relations/proxy.rb +4 -1
- data/lib/filemaker/model/selectable.rb +2 -2
- data/lib/filemaker/model/types/attachment.rb +102 -0
- data/lib/filemaker/model/types/email.rb +41 -0
- data/lib/filemaker/record.rb +7 -4
- data/lib/filemaker/server.rb +33 -13
- data/lib/filemaker/version.rb +1 -1
- data/lib/generators/filemaker/model/model_generator.rb +2 -1
- data/spec/filemaker/configuration_spec.rb +1 -1
- data/spec/filemaker/layout_spec.rb +8 -8
- data/spec/filemaker/metadata/field_spec.rb +9 -1
- data/spec/filemaker/model/criteria_spec.rb +17 -17
- data/spec/filemaker/model/relations_spec.rb +5 -0
- data/spec/filemaker/model_spec.rb +66 -1
- data/spec/filemaker/resultset_spec.rb +1 -1
- data/spec/filemaker/store/database_store_spec.rb +1 -1
- data/spec/support/filemaker.yml +2 -2
- data/spec/support/models.rb +3 -1
- metadata +35 -3
@@ -5,7 +5,7 @@ module Filemaker
|
|
5
5
|
def page(value)
|
6
6
|
value = 1 if value.nil?
|
7
7
|
chains << :page
|
8
|
-
@_page = value.to_i
|
8
|
+
@_page = positive_page(value.to_i)
|
9
9
|
update_skip
|
10
10
|
end
|
11
11
|
|
@@ -37,6 +37,11 @@ module Filemaker
|
|
37
37
|
skip(skip) unless skip.zero?
|
38
38
|
self
|
39
39
|
end
|
40
|
+
|
41
|
+
def positive_page(page)
|
42
|
+
return 1 if page.nil? || !page.is_a?(Integer)
|
43
|
+
page.positive? ? page : 1
|
44
|
+
end
|
40
45
|
end
|
41
46
|
end
|
42
47
|
end
|
@@ -26,8 +26,11 @@ module Filemaker
|
|
26
26
|
@class_name.constantize
|
27
27
|
end
|
28
28
|
|
29
|
+
# Rubocop will complain and ask to fallback on `super`, but we won't be
|
30
|
+
# able to do that because the target may have method that throw
|
31
|
+
# exception
|
29
32
|
def method_missing(name, *args, &block)
|
30
|
-
target.send(name, *args, &block)
|
33
|
+
target.send(name, *args, &block)
|
31
34
|
end
|
32
35
|
|
33
36
|
def respond_to_missing?(method_name, include_private = false)
|
@@ -56,7 +56,7 @@ module Filemaker
|
|
56
56
|
first
|
57
57
|
end
|
58
58
|
|
59
|
-
%w
|
59
|
+
%w[eq cn bw ew gt gte lt lte neq].each do |operator|
|
60
60
|
define_method(operator) do |criterion, &block|
|
61
61
|
if chains.include?(:in)
|
62
62
|
raise Filemaker::Errors::MixedClauseError,
|
@@ -82,7 +82,7 @@ module Filemaker
|
|
82
82
|
|
83
83
|
# Inside define_method, we cannot have yield or block_given?, so we
|
84
84
|
# just use &block
|
85
|
-
block
|
85
|
+
block&.call(options)
|
86
86
|
self
|
87
87
|
end
|
88
88
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'mimemagic'
|
3
|
+
|
4
|
+
module Filemaker
|
5
|
+
module Model
|
6
|
+
module Types
|
7
|
+
class Attachment
|
8
|
+
attr_reader :_body, :content_type, :extension, :klass
|
9
|
+
|
10
|
+
def initialize(value, klass)
|
11
|
+
@value = value
|
12
|
+
@klass = klass
|
13
|
+
end
|
14
|
+
|
15
|
+
def url
|
16
|
+
@value.to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
def file_extension
|
20
|
+
# We need to use .path to eliminate query string
|
21
|
+
File.extname(URI.parse(url).path)
|
22
|
+
end
|
23
|
+
|
24
|
+
def filename
|
25
|
+
return if url.blank?
|
26
|
+
File.basename(URI.parse(url).path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def body
|
30
|
+
return @_body if defined?(@_body)
|
31
|
+
|
32
|
+
valid_files = %w[
|
33
|
+
.pdf
|
34
|
+
.jpeg .jpg .png .gif .tif .tiff
|
35
|
+
.doc .docx .xls .xlsx .ppt .pptx .pptm
|
36
|
+
.txt
|
37
|
+
.rar .zip .webarchive
|
38
|
+
.htm .html
|
39
|
+
.java
|
40
|
+
]
|
41
|
+
|
42
|
+
@_body = download_protected_file
|
43
|
+
|
44
|
+
if !file_extension.blank? &&
|
45
|
+
valid_files.include?(file_extension.try(:downcase))
|
46
|
+
|
47
|
+
@content_type = MimeMagic.by_extension(file_extension).try(:type)
|
48
|
+
@extension = file_extension
|
49
|
+
else
|
50
|
+
mime_type = MimeMagic.by_magic(@_body)
|
51
|
+
|
52
|
+
unless mime_type.blank?
|
53
|
+
case mime_type.type.downcase
|
54
|
+
when 'application/msword'
|
55
|
+
@content_type = 'application/msword'
|
56
|
+
@extension = '.doc'
|
57
|
+
when 'application/pdf'
|
58
|
+
@content_type = 'application/pdf'
|
59
|
+
@extension = '.pdf'
|
60
|
+
when 'application/x-ole-storage'
|
61
|
+
@content_type = 'application/vnd.ms-excel'
|
62
|
+
@extension = '.xls'
|
63
|
+
when 'application/vnd.ms-excel'
|
64
|
+
@content_type = 'application/vnd.ms-excel'
|
65
|
+
@extension = '.xls'
|
66
|
+
when 'image/jpeg'
|
67
|
+
@content_type = 'image/jpeg'
|
68
|
+
@extension = '.jpg'
|
69
|
+
when 'image/png'
|
70
|
+
@content_type = 'image/png'
|
71
|
+
@extension = '.png'
|
72
|
+
when 'application/vnd.oasis.opendocument.text'
|
73
|
+
@content_type = 'application/vnd.oasis.opendocument.text'
|
74
|
+
@extension = '.odt'
|
75
|
+
else
|
76
|
+
# No choice, we have to assign it somehow
|
77
|
+
@content_type = mime_type.type
|
78
|
+
@extension = MIME::Types[@content_type].first
|
79
|
+
.try(:extensions)
|
80
|
+
.try(:first)
|
81
|
+
@extension = ".#{@extension}" if @extension
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
@_body
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def download_protected_file
|
92
|
+
req = Net::HTTP::Get.new(url)
|
93
|
+
req.basic_auth(klass.server.account_name, klass.server.password)
|
94
|
+
res = Net::HTTP.new(klass.server.host, 80)
|
95
|
+
res = res.start { |http| http.request(req) }
|
96
|
+
|
97
|
+
res.body
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Filemaker
|
2
|
+
module Model
|
3
|
+
module Types
|
4
|
+
class Email
|
5
|
+
def initialize(value)
|
6
|
+
# to_s incoming value, this can prevent similar type from
|
7
|
+
# nesting deeply
|
8
|
+
@value = value.nil? ? nil : value.to_s
|
9
|
+
end
|
10
|
+
|
11
|
+
def value
|
12
|
+
email = @value&.strip&.split(%r{,|\(|\/|\s})
|
13
|
+
&.reject(&:empty?)&.first&.downcase
|
14
|
+
&.gsub(/[\uFF20\uFE6B\u0040]/, '@')
|
15
|
+
|
16
|
+
email&.include?('@') ? email : nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def value=(v)
|
20
|
+
self.value = v
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
value
|
25
|
+
end
|
26
|
+
|
27
|
+
def ==(other)
|
28
|
+
to_s == other.to_s
|
29
|
+
end
|
30
|
+
alias eql? ==
|
31
|
+
|
32
|
+
# In FileMaker, at-sign is for wildcard query. In order to search for
|
33
|
+
# email, we need to escape at-sign. Note the single-quote escaping!
|
34
|
+
# e.g. 'a@host.com' will become 'a\\@host.com'
|
35
|
+
def to_query
|
36
|
+
value.gsub('@', '\@')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/filemaker/record.rb
CHANGED
@@ -51,10 +51,13 @@ module Filemaker
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def []=(key, value)
|
54
|
-
|
55
|
-
|
54
|
+
if @ready
|
55
|
+
raise(Filemaker::Errors::InvalidFieldError, "Invalid field: #{key}") \
|
56
56
|
unless key?(key)
|
57
|
-
|
57
|
+
@dirty[key] = value
|
58
|
+
else
|
59
|
+
super
|
60
|
+
end
|
58
61
|
end
|
59
62
|
|
60
63
|
private
|
@@ -87,7 +90,7 @@ module Filemaker
|
|
87
90
|
super
|
88
91
|
end
|
89
92
|
|
90
|
-
def respond_to_missing?
|
93
|
+
def respond_to_missing?(method_name, include_private = false)
|
91
94
|
super
|
92
95
|
end
|
93
96
|
end
|
data/lib/filemaker/server.rb
CHANGED
@@ -48,11 +48,23 @@ module Filemaker
|
|
48
48
|
response = @connection.public_send(method, endpoint, params)
|
49
49
|
|
50
50
|
case response.status
|
51
|
-
when 200
|
52
|
-
|
53
|
-
when
|
54
|
-
|
55
|
-
|
51
|
+
when 200
|
52
|
+
[response, params]
|
53
|
+
when 401
|
54
|
+
raise Errors::AuthenticationError,
|
55
|
+
"[#{response.status}] Authentication failed."
|
56
|
+
when 0
|
57
|
+
raise Errors::CommunicationError,
|
58
|
+
"[#{response.status}] Empty response."
|
59
|
+
when 404
|
60
|
+
raise Errors::CommunicationError,
|
61
|
+
"[#{response.status}] Not found"
|
62
|
+
when 302
|
63
|
+
raise Errors::CommunicationError,
|
64
|
+
"[#{response.status}] Redirect not supported"
|
65
|
+
when 502
|
66
|
+
raise Errors::CommunicationError,
|
67
|
+
"[#{response.status}] Bad gateway. Too many records."
|
56
68
|
else
|
57
69
|
msg = "Unknown response status = #{response.status}"
|
58
70
|
raise Errors::CommunicationError, msg
|
@@ -70,21 +82,29 @@ module Filemaker
|
|
70
82
|
|
71
83
|
Faraday.new(@config.url, faraday_options) do |faraday|
|
72
84
|
faraday.request :url_encoded
|
73
|
-
faraday.adapter :typhoeus
|
74
85
|
faraday.headers[:user_agent] = \
|
75
86
|
"filemaker-ruby-#{Filemaker::VERSION}".freeze
|
76
87
|
faraday.basic_auth @config.account_name, @config.password
|
88
|
+
|
89
|
+
# The order of the middleware is important, so adapter must be the last
|
90
|
+
faraday.adapter :typhoeus
|
77
91
|
end
|
78
92
|
end
|
79
93
|
|
94
|
+
# {"-db"=>"mydb", "-lay"=>"mylay", "email"=>"a@b.com", "updated_at": Date}
|
80
95
|
def serialize_args(args)
|
81
96
|
return {} if args.nil?
|
82
97
|
|
83
98
|
args.each do |key, value|
|
84
99
|
case value
|
85
|
-
when DateTime
|
86
|
-
|
87
|
-
when
|
100
|
+
when DateTime
|
101
|
+
args[key] = value.strftime('%m/%d/%Y %H:%M:%S')
|
102
|
+
when Date
|
103
|
+
args[key] = value.strftime('%m/%d/%Y')
|
104
|
+
when Time
|
105
|
+
args[key] = value.strftime('%H:%M')
|
106
|
+
when Filemaker::Model::Types::Email
|
107
|
+
args[key] = value.to_query
|
88
108
|
else
|
89
109
|
# Especially for range operator (...), we want to output as String
|
90
110
|
args[key] = value.to_s
|
@@ -164,10 +184,10 @@ module Filemaker
|
|
164
184
|
|
165
185
|
# TODO: Should we convert it to string so 'cURL' will work also?
|
166
186
|
def log_action(params)
|
167
|
-
case @config.log
|
168
|
-
when
|
169
|
-
when
|
170
|
-
when
|
187
|
+
case @config.log.to_s
|
188
|
+
when 'simple' then log_simple(params)
|
189
|
+
when 'curl' then log_curl(params)
|
190
|
+
when 'curl_auth' then log_curl(params, true)
|
171
191
|
end
|
172
192
|
end
|
173
193
|
|
data/lib/filemaker/version.rb
CHANGED
@@ -8,7 +8,7 @@ describe 'Configuration' do
|
|
8
8
|
expect(Filemaker.registry['default'].account_name).to eq \
|
9
9
|
'FILEMAKER_ACCOUNT_NAME'
|
10
10
|
expect(Filemaker.registry['default'].ssl).to eq({ 'verify' => false })
|
11
|
-
expect(Filemaker.registry['default'].log).to eq
|
11
|
+
expect(Filemaker.registry['default'].log).to eq 'curl'
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'raises ConfigurationError for wrong environment' do
|
@@ -46,7 +46,7 @@ describe Filemaker::Layout do
|
|
46
46
|
it 'allows -max, -skip' do
|
47
47
|
resultset = @layout.findall(
|
48
48
|
max: 5, skip: 10,
|
49
|
-
sortfield: %w
|
49
|
+
sortfield: %w[f1 f2], sortorder: ['descend']
|
50
50
|
)
|
51
51
|
|
52
52
|
expect(resultset.params['-max']).to eq 5
|
@@ -60,8 +60,8 @@ describe Filemaker::Layout do
|
|
60
60
|
it 'will not accept more than 9 sortfields' do
|
61
61
|
expect do
|
62
62
|
@layout.findall(
|
63
|
-
sortfield: %w
|
64
|
-
sortorder: %w
|
63
|
+
sortfield: %w[f1 f2 f3 f4 f5 f6 f7 f8 f9 f10],
|
64
|
+
sortorder: %w[o1 o2 o3 o4 o5 o6 o7 o8 o9]
|
65
65
|
)
|
66
66
|
end.to raise_error Filemaker::Errors::ParameterError
|
67
67
|
end
|
@@ -69,8 +69,8 @@ describe Filemaker::Layout do
|
|
69
69
|
it 'will not accept more than 9 sortorders' do
|
70
70
|
expect do
|
71
71
|
@layout.findall(
|
72
|
-
sortfield: %w
|
73
|
-
sortorder: %w
|
72
|
+
sortfield: %w[f1 f2 f3 f4 f5 f6 f7 f8 f9],
|
73
|
+
sortorder: %w[o1 o2 o3 o4 o5 o6 o7 o8 o9 o10]
|
74
74
|
)
|
75
75
|
end.to raise_error Filemaker::Errors::ParameterError
|
76
76
|
end
|
@@ -174,7 +174,7 @@ describe Filemaker::Layout do
|
|
174
174
|
|
175
175
|
describe 'query' do
|
176
176
|
it 'transform {a: [1,2]} to (q0);(q1)' do
|
177
|
-
resultset = @layout.query(status: %w
|
177
|
+
resultset = @layout.query(status: %w[open closed])
|
178
178
|
expect(resultset.params['-query']).to eq '(q0);(q1)'
|
179
179
|
end
|
180
180
|
|
@@ -205,7 +205,7 @@ describe Filemaker::Layout do
|
|
205
205
|
end
|
206
206
|
|
207
207
|
it 'can do -script.prefind.param' do
|
208
|
-
resultset = @layout.find(1, script_prefind: %w
|
208
|
+
resultset = @layout.find(1, script_prefind: %w[Unique yes])
|
209
209
|
expect(resultset.params['-script.prefind']).to eq 'Unique'
|
210
210
|
expect(resultset.params['-script.prefind.param']).to eq 'yes'
|
211
211
|
end
|
@@ -216,7 +216,7 @@ describe Filemaker::Layout do
|
|
216
216
|
end
|
217
217
|
|
218
218
|
it 'can do -script.presort.param' do
|
219
|
-
resultset = @layout.find(1, script_presort: %w
|
219
|
+
resultset = @layout.find(1, script_presort: %w[Order ascend])
|
220
220
|
expect(resultset.params['-script.presort']).to eq 'Order'
|
221
221
|
expect(resultset.params['-script.presort.param']).to eq 'ascend'
|
222
222
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
describe Filemaker::Metadata::Field do
|
2
2
|
let(:server) do
|
3
3
|
Filemaker::Server.new do |config|
|
4
|
-
config.host = '
|
4
|
+
config.host = 'host'
|
5
5
|
config.account_name = 'account_name'
|
6
6
|
config.password = 'password'
|
7
|
+
config.ssl = { verify: false }
|
7
8
|
end
|
8
9
|
end
|
9
10
|
let(:xml) { import_xml_as_string('portal.xml') }
|
@@ -69,5 +70,12 @@ describe Filemaker::Metadata::Field do
|
|
69
70
|
expect(field.coerce('/fmi/xml/cnt/1234jpg').to_s).to eq \
|
70
71
|
'https://host/fmi/xml/cnt/1234jpg'
|
71
72
|
end
|
73
|
+
|
74
|
+
it 'converts container with existing http' do
|
75
|
+
allow(field).to receive(:data_type).and_return 'container'
|
76
|
+
expect(field.coerce('http://host/fmi/xml/cnt/1234jpg')).to be_a URI
|
77
|
+
expect(field.coerce('http://host/fmi/xml/cnt/1234jpg').to_s).to eq \
|
78
|
+
'http://host/fmi/xml/cnt/1234jpg'
|
79
|
+
end
|
72
80
|
end
|
73
81
|
end
|
@@ -6,7 +6,7 @@ describe Filemaker::Model::Criteria do
|
|
6
6
|
describe 'where' do
|
7
7
|
it 'raises MixedClauseError if mixed with -findquery' do
|
8
8
|
expect do
|
9
|
-
criteria.in(status: %w
|
9
|
+
criteria.in(status: %w[pending subscribed]).where(name: 'Bob')
|
10
10
|
end.to raise_error Filemaker::Errors::MixedClauseError
|
11
11
|
end
|
12
12
|
|
@@ -85,7 +85,7 @@ describe Filemaker::Model::Criteria do
|
|
85
85
|
context 'comparison operators' do
|
86
86
|
it 'only works on `where` query' do
|
87
87
|
expect do
|
88
|
-
criteria.in(status: %w
|
88
|
+
criteria.in(status: %w[pending subscribed]).eq(name: 'Bob')
|
89
89
|
end.to raise_error Filemaker::Errors::MixedClauseError
|
90
90
|
end
|
91
91
|
|
@@ -121,32 +121,32 @@ describe Filemaker::Model::Criteria do
|
|
121
121
|
describe 'in' do
|
122
122
|
it 'raises MixedClauseError if mixed with -find' do
|
123
123
|
expect do
|
124
|
-
criteria.where(name: 'Bob').in(status: %w
|
124
|
+
criteria.where(name: 'Bob').in(status: %w[pending subscribed])
|
125
125
|
end.to raise_error Filemaker::Errors::MixedClauseError
|
126
126
|
end
|
127
127
|
|
128
128
|
it '{a: [1, 2]} to (q0);(q1)' do
|
129
|
-
criteria.in(name: %w
|
129
|
+
criteria.in(name: %w[Bob Lee])
|
130
130
|
compound_find = cf.new(criteria.selector)
|
131
131
|
expect(compound_find.key_maps_string).to eq '(q0);(q1)'
|
132
|
-
expect(criteria.selector).to eq [{ 'name' => %w
|
132
|
+
expect(criteria.selector).to eq [{ 'name' => %w[Bob Lee] }]
|
133
133
|
end
|
134
134
|
|
135
135
|
it '{a: [1, 2], b: [3, 4]} to (q0,q2);(q0,q3);(q1,q2);(q1,q3)' do
|
136
|
-
criteria.in(name: %w
|
136
|
+
criteria.in(name: %w[Bob Lee], age: ['20', 30])
|
137
137
|
compound_find = cf.new(criteria.selector)
|
138
138
|
expect(compound_find.key_maps_string).to eq \
|
139
139
|
'(q0,q2);(q0,q3);(q1,q2);(q1,q3)'
|
140
140
|
expect(criteria.selector).to eq \
|
141
|
-
[{ 'name' => %w
|
141
|
+
[{ 'name' => %w[Bob Lee], 'passage of time' => [20, 30] }]
|
142
142
|
end
|
143
143
|
|
144
144
|
it '{a: [1, 2], b: 3} to (q0,q2);(q1,q2)' do
|
145
|
-
criteria.in(name: %w
|
145
|
+
criteria.in(name: %w[Bob Lee], age: '30')
|
146
146
|
compound_find = cf.new(criteria.selector)
|
147
147
|
expect(compound_find.key_maps_string).to eq '(q0,q2);(q1,q2)'
|
148
148
|
expect(criteria.selector).to eq \
|
149
|
-
[{ 'name' => %w
|
149
|
+
[{ 'name' => %w[Bob Lee], 'passage of time' => 30 }]
|
150
150
|
end
|
151
151
|
|
152
152
|
it '{a: 1, b: 2} to (q0,q1)' do
|
@@ -166,11 +166,11 @@ describe Filemaker::Model::Criteria do
|
|
166
166
|
end
|
167
167
|
|
168
168
|
it '[{a: [1, 2]}, {b: [1, 2]}] to (q0);(q1);(q2);(q3)' do
|
169
|
-
criteria.in([{ name: %w
|
169
|
+
criteria.in([{ name: %w[Bob Lee] }, { age: [20, 30] }])
|
170
170
|
compound_find = cf.new(criteria.selector)
|
171
171
|
expect(compound_find.key_maps_string).to eq '(q0);(q1);(q2);(q3)'
|
172
172
|
expect(criteria.selector).to eq \
|
173
|
-
[{ 'name' => %w
|
173
|
+
[{ 'name' => %w[Bob Lee] }, { 'passage of time' => [20, 30] }]
|
174
174
|
end
|
175
175
|
|
176
176
|
it '[{a: 1}, {b: 2}] to (q0);(q1)' do
|
@@ -200,20 +200,20 @@ describe Filemaker::Model::Criteria do
|
|
200
200
|
|
201
201
|
describe 'not_in' do
|
202
202
|
it '{a: [1, 2]} to !(q0);!(q1)' do
|
203
|
-
criteria.not_in(name: %w
|
203
|
+
criteria.not_in(name: %w[Bob Lee])
|
204
204
|
compound_find = cf.new(criteria.selector)
|
205
205
|
expect(compound_find.key_maps_string).to eq '!(q0);!(q1)'
|
206
206
|
end
|
207
207
|
|
208
208
|
it '{a: [1, 2], b: [3, 4]} to !(q0,q2);!(q0,q3);!(q1,q2);!(q1,q3)' do
|
209
|
-
criteria.not_in(name: %w
|
209
|
+
criteria.not_in(name: %w[Bob Lee], age: ['20', 30])
|
210
210
|
compound_find = cf.new(criteria.selector)
|
211
211
|
expect(compound_find.key_maps_string).to eq \
|
212
212
|
'!(q0,q2);!(q0,q3);!(q1,q2);!(q1,q3)'
|
213
213
|
end
|
214
214
|
|
215
215
|
it '{a: [1, 2], b: 3} to !(q0,q2);!(q1,q2)' do
|
216
|
-
criteria.not_in(name: %w
|
216
|
+
criteria.not_in(name: %w[Bob Lee], age: '30')
|
217
217
|
compound_find = cf.new(criteria.selector)
|
218
218
|
expect(compound_find.key_maps_string).to eq '!(q0,q2);!(q1,q2)'
|
219
219
|
end
|
@@ -231,7 +231,7 @@ describe Filemaker::Model::Criteria do
|
|
231
231
|
end
|
232
232
|
|
233
233
|
it '[{a: [1, 2]}, {b: [1, 2]}] to !(q0);!(q1);!(q2);!(q3)' do
|
234
|
-
criteria.not_in([{ name: %w
|
234
|
+
criteria.not_in([{ name: %w[Bob Lee] }, { age: [20, 30] }])
|
235
235
|
compound_find = cf.new(criteria.selector)
|
236
236
|
expect(compound_find.key_maps_string).to eq '!(q0);!(q1);!(q2);!(q3)'
|
237
237
|
end
|
@@ -255,7 +255,7 @@ describe Filemaker::Model::Criteria do
|
|
255
255
|
end
|
256
256
|
|
257
257
|
it 'using in and not_in at the same time' do
|
258
|
-
criteria.in(name: %w
|
258
|
+
criteria.in(name: %w[Bob Lee]).not_in(age: 20, email: 'A')
|
259
259
|
compound_find = cf.new(criteria.selector)
|
260
260
|
expect(compound_find.key_maps_string).to eq '(q0);(q1);!(q2,q3)'
|
261
261
|
end
|
@@ -297,7 +297,7 @@ describe Filemaker::Model::Criteria do
|
|
297
297
|
|
298
298
|
it 'will default to asc for missing order' do
|
299
299
|
criteria.order('name, email')
|
300
|
-
expect(criteria.options[:sortorder]).to eq %w
|
300
|
+
expect(criteria.options[:sortorder]).to eq %w[ascend ascend]
|
301
301
|
end
|
302
302
|
|
303
303
|
it 'will use real FileMaker fieldname' do
|