ruby-factual 0.1.3 → 0.1.4
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.
- data/README.md +39 -34
- data/lib/factual.rb +54 -14
- data/test/unit/adapter.rb +1 -1
- data/test/unit/table.rb +12 -7
- metadata +4 -21
data/README.md
CHANGED
@@ -1,37 +1,42 @@
|
|
1
1
|
## Sample Usage
|
2
2
|
|
3
3
|
A block of code is worth a thousand words.
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
>
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
gem 'ruby-factual'
|
7
|
+
require 'factual'
|
8
|
+
|
9
|
+
api = Factual::Api.new(:api_key => "<YOUR_FACTUAL_API_KEY>")
|
10
|
+
|
11
|
+
# get table and its metadata
|
12
|
+
# table metadata: name, description, rating, source, creator, created_at,
|
13
|
+
# updated_at, total_row_count, geo_enabled, downloadable,
|
14
|
+
# fields (array of hash)
|
15
|
+
table = api.get_table("g9R1u2")
|
16
|
+
puts table.name, table.creator
|
17
|
+
|
18
|
+
# read rows after filtering and sorting
|
19
|
+
table.filter(:two_letter_abbrev => "CA").sort(:state => -1).page(1, :size => 5).each_row do |state_info|
|
20
|
+
|
21
|
+
# read facts
|
22
|
+
# fact attributes: value, subject_key, field_ref, field (hash)
|
23
|
+
fact = state_info["state"]
|
24
|
+
puts fact.value, fact.subject_key
|
25
|
+
|
26
|
+
# write facts
|
27
|
+
if fact.input("Kalifornia", :source => "source", :comment => "comment")
|
28
|
+
puts "inputted"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# you can also get rows by search
|
33
|
+
row = table.search("hawaii").find_one
|
34
|
+
puts row["state"]
|
35
|
+
|
36
|
+
# add a row
|
37
|
+
ret = table.input(:state => "Nebraska", :two_letter_abbrev => "NE")
|
38
|
+
|
39
|
+
# get a row object from resp
|
40
|
+
subject_key = ret["subjectKey"]
|
41
|
+
row = Factual::Row.new(table, subject_key)
|
42
|
+
puts row["state"].value
|
data/lib/factual.rb
CHANGED
@@ -94,6 +94,20 @@ module Factual
|
|
94
94
|
return self
|
95
95
|
end
|
96
96
|
|
97
|
+
# Define table search queries, it can be chained before +find_one+ or +each_row+.
|
98
|
+
#
|
99
|
+
# The params can be:
|
100
|
+
# * A query string
|
101
|
+
# * An array of query strings
|
102
|
+
#
|
103
|
+
# Samples:
|
104
|
+
# table.serach('starbucks').find_one # one query
|
105
|
+
# table.search('starbucks', 'burger king').find_one # multiple queries
|
106
|
+
def search(*queries)
|
107
|
+
@searches = queries
|
108
|
+
return self
|
109
|
+
end
|
110
|
+
|
97
111
|
# Define table filters, it can be chained before +find_one+ or +each_row+.
|
98
112
|
#
|
99
113
|
# The params can be:
|
@@ -132,12 +146,17 @@ module Factual
|
|
132
146
|
# Samples:
|
133
147
|
# * <tt>table.filter(:state => 'CA').find_one</tt>
|
134
148
|
# * <tt>table.filter(:state => 'CA').sort(:city => 1).find_one</tt>
|
149
|
+
# * <tt>table.filter(:state => 'CA').search('starbucks').sort(:city => 1).find_one</tt>
|
135
150
|
def find_one
|
136
|
-
resp = @adapter.read_table(@table_key,
|
137
|
-
|
151
|
+
resp = @adapter.read_table(@table_key,
|
152
|
+
:filters => @filters,
|
153
|
+
:searches => @searches,
|
154
|
+
:sorts => @sorts,
|
155
|
+
:page_size => 1)
|
156
|
+
row_data = resp["data"].first
|
138
157
|
|
139
158
|
if row_data.is_a?(Array)
|
140
|
-
subject_key = row_data.
|
159
|
+
subject_key = row_data.shift
|
141
160
|
return Row.new(self, subject_key, row_data)
|
142
161
|
else
|
143
162
|
return nil
|
@@ -147,17 +166,22 @@ module Factual
|
|
147
166
|
# An iterator on each row (a Factual::Row object) of the filtered and/or sorted table data
|
148
167
|
#
|
149
168
|
# Samples:
|
150
|
-
# table.filter(:state => 'CA').sort(:city => 1).each do |row|
|
169
|
+
# table.filter(:state => 'CA').search('starbucks').sort(:city => 1).each do |row|
|
151
170
|
# puts row.inspect
|
152
171
|
# end
|
153
172
|
def each_row
|
154
|
-
resp = @adapter.read_table(@table_key,
|
173
|
+
resp = @adapter.read_table(@table_key,
|
174
|
+
:filters => @filters,
|
175
|
+
:searches => @searches,
|
176
|
+
:sorts => @sorts,
|
177
|
+
:page_size => @page_size,
|
178
|
+
:page => @page)
|
155
179
|
|
156
180
|
@total_rows = resp["total_rows"]
|
157
181
|
rows = resp["data"]
|
158
182
|
|
159
183
|
rows.each do |row_data|
|
160
|
-
subject_key = row_data.
|
184
|
+
subject_key = row_data.shift
|
161
185
|
row = Row.new(self, subject_key, row_data)
|
162
186
|
yield(row) if block_given?
|
163
187
|
end
|
@@ -236,19 +260,22 @@ module Factual
|
|
236
260
|
@adapter = @table.adapter
|
237
261
|
|
238
262
|
if row_data.empty? && subject_key
|
263
|
+
single_row_mode = true
|
239
264
|
row_data = @adapter.read_row(@table_key, subject_key)
|
240
265
|
end
|
241
266
|
|
267
|
+
idx_offset = single_row_mode ? 1 : 0;
|
268
|
+
|
242
269
|
@subject = []
|
243
270
|
@fields.each_with_index do |f, idx|
|
244
271
|
next unless f["isPrimary"]
|
245
|
-
@subject << row_data[idx+
|
272
|
+
@subject << row_data[idx + idx_offset]
|
246
273
|
end
|
247
274
|
|
248
275
|
@facts_hash = {}
|
249
276
|
@fields.each_with_index do |f, idx|
|
250
277
|
next if f["isPrimary"]
|
251
|
-
@facts_hash[f["field_ref"]] = Fact.new(@table, @subject_key, f, row_data[idx+
|
278
|
+
@facts_hash[f["field_ref"]] = Fact.new(@table, @subject_key, f, row_data[idx + idx_offset])
|
252
279
|
end
|
253
280
|
end
|
254
281
|
|
@@ -292,9 +319,10 @@ module Factual
|
|
292
319
|
return false if value.nil?
|
293
320
|
|
294
321
|
hash = opts.merge({
|
295
|
-
:subjectKey => @subject_key,
|
296
|
-
:
|
297
|
-
|
322
|
+
:subjectKey => @subject_key.first,
|
323
|
+
:values => [{
|
324
|
+
:fieldId => @field['id'],
|
325
|
+
:value => value }]
|
298
326
|
})
|
299
327
|
|
300
328
|
@adapter.input(@table_key, hash)
|
@@ -382,12 +410,20 @@ module Factual
|
|
382
410
|
return row_data
|
383
411
|
end
|
384
412
|
|
385
|
-
def read_table(table_key,
|
413
|
+
def read_table(table_key, options={})
|
414
|
+
filters = options[:filters]
|
415
|
+
sorts = options[:sorts]
|
416
|
+
searches = options[:searches]
|
417
|
+
page_size = options[:page_size]
|
418
|
+
page = options[:page]
|
419
|
+
|
386
420
|
limit = page_size.to_i
|
387
421
|
limit = DEFAULT_LIMIT unless limit > 0
|
388
422
|
offset = (page.to_i - 1) * limit
|
389
423
|
offset = 0 unless offset > 0
|
390
424
|
|
425
|
+
filters = (filters || {}).merge( "$search" => searches) if searches
|
426
|
+
|
391
427
|
filters_query = "&filters=" + CGI.escape(filters.to_json) if filters
|
392
428
|
|
393
429
|
if sorts
|
@@ -395,7 +431,8 @@ module Factual
|
|
395
431
|
sorts_query = "&sort=" + sorts.to_json
|
396
432
|
end
|
397
433
|
|
398
|
-
url = "/tables/#{table_key}/read.jsaml?limit=#{limit}&offset=#{offset}"
|
434
|
+
url = "/tables/#{table_key}/read.jsaml?limit=#{limit}&offset=#{offset}"
|
435
|
+
url += filters_query.to_s + sorts_query.to_s
|
399
436
|
resp = api_call(url)
|
400
437
|
|
401
438
|
return resp["response"]
|
@@ -410,7 +447,10 @@ module Factual
|
|
410
447
|
|
411
448
|
def input(table_key, params)
|
412
449
|
token = params.delete(:token)
|
413
|
-
query_string = params.to_a.collect
|
450
|
+
query_string = params.to_a.collect do |k,v|
|
451
|
+
v_string = (v.is_a?(Hash) || v.is_a?(Array)) ? v.to_json : v.to_s
|
452
|
+
CGI.escape(k.to_s) + '=' + CGI.escape(v_string)
|
453
|
+
end.join('&')
|
414
454
|
|
415
455
|
url = "/tables/#{table_key}/input.js?" + query_string
|
416
456
|
url += "&token=" + token if token
|
data/test/unit/adapter.rb
CHANGED
@@ -40,7 +40,7 @@ class AdapterTest < Factual::TestCase # :nodoc:
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def test_reading_table_with_filter
|
43
|
-
resp = @adapter.read_table(TABLE_KEY, {:two_letter_abbrev => 'CA'})
|
43
|
+
resp = @adapter.read_table(TABLE_KEY, :filters => {:two_letter_abbrev => 'CA'})
|
44
44
|
assert_equal resp['total_rows'], 1
|
45
45
|
end
|
46
46
|
|
data/test/unit/table.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'lib/factual'
|
2
|
-
require 'test/unit/helper'
|
1
|
+
require './lib/factual'
|
2
|
+
require './test/unit/helper'
|
3
3
|
|
4
4
|
class TableTest < Factual::TestCase # :nodoc:
|
5
5
|
def setup
|
@@ -23,6 +23,14 @@ class TableTest < Factual::TestCase # :nodoc:
|
|
23
23
|
assert_equal states.length, TOTAL_ROWS
|
24
24
|
end
|
25
25
|
|
26
|
+
def test_search
|
27
|
+
row = @table.search('hawaii').find_one
|
28
|
+
assert_equal row["state"].value, "hawaii"
|
29
|
+
|
30
|
+
row = @table.search('hi', 'hawaii').find_one
|
31
|
+
assert_equal row["state"].value, "hawaii"
|
32
|
+
end
|
33
|
+
|
26
34
|
def test_filtering
|
27
35
|
row = @table.filter(:two_letter_abbrev => 'WA').find_one
|
28
36
|
assert_equal row["state"].value, "Washington"
|
@@ -62,12 +70,9 @@ class TableTest < Factual::TestCase # :nodoc:
|
|
62
70
|
def test_adding_row
|
63
71
|
row = @table.input(:two_letter_abbrev => 'NE', :state => 'Nebraska')
|
64
72
|
end
|
65
|
-
|
73
|
+
|
66
74
|
def test_row
|
67
75
|
row = Factual::Row.new(@table, SUBJECT_KEY)
|
68
|
-
assert_equal row[
|
69
|
-
end
|
70
|
-
|
71
|
-
def test_fact
|
76
|
+
assert_equal row['state'].value, 'California'
|
72
77
|
end
|
73
78
|
end
|
metadata
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-factual
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 3
|
10
|
-
version: 0.1.3
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.4
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- Forrest Cao
|
@@ -15,7 +10,7 @@ autorequire:
|
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
12
|
|
18
|
-
date: 2011-
|
13
|
+
date: 2011-06-17 00:00:00 +08:00
|
19
14
|
default_executable:
|
20
15
|
dependencies:
|
21
16
|
- !ruby/object:Gem::Dependency
|
@@ -26,11 +21,6 @@ dependencies:
|
|
26
21
|
requirements:
|
27
22
|
- - ">="
|
28
23
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 31
|
30
|
-
segments:
|
31
|
-
- 1
|
32
|
-
- 2
|
33
|
-
- 0
|
34
24
|
version: 1.2.0
|
35
25
|
type: :runtime
|
36
26
|
version_requirements: *id001
|
@@ -66,24 +56,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
66
56
|
requirements:
|
67
57
|
- - ">="
|
68
58
|
- !ruby/object:Gem::Version
|
69
|
-
hash: 3
|
70
|
-
segments:
|
71
|
-
- 0
|
72
59
|
version: "0"
|
73
60
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
61
|
none: false
|
75
62
|
requirements:
|
76
63
|
- - ">="
|
77
64
|
- !ruby/object:Gem::Version
|
78
|
-
hash: 11
|
79
|
-
segments:
|
80
|
-
- 1
|
81
|
-
- 2
|
82
65
|
version: "1.2"
|
83
66
|
requirements: []
|
84
67
|
|
85
68
|
rubyforge_project:
|
86
|
-
rubygems_version: 1.
|
69
|
+
rubygems_version: 1.6.2
|
87
70
|
signing_key:
|
88
71
|
specification_version: 3
|
89
72
|
summary: ""
|