filemaker 0.0.18 → 0.0.19
Sign up to get free protection for your applications and to get access to all the features.
- 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
|