ruby-factual 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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
- > require 'rubygems'
5
- > gem 'ruby-factual'
6
- > require 'factual'
7
- >
8
- > api = Factual::Api.new(:api_key => "<YOUR_FACTUAL_API_KEY>")
9
- >
10
- > # get table and its metadata
11
- > # table metadata: name, description, rating, source, creator, created_at,
12
- > # updated_at, total_row_count, geo_enabled, downloadable,
13
- > # fields (array of hash)
14
- > table = api.get_table("g9R1u2")
15
- > puts table.name, table.creator
16
- >
17
- > # read rows after filtering and sorting
18
- > table.filter(:two_letter_abbrev => "CA").sort(:state => -1).page(1, :size => 5).each_row do |state_info|
19
- >
20
- > # read facts
21
- > # fact attributes: value, subject_key, field_ref, field (hash)
22
- > fact = state_info["state"]
23
- > puts fact.value, fact.subject_key
24
- >
25
- > # write facts
26
- > if fact.input("Kalifornia", :source => "source", :comment => "comment")
27
- > puts "inputted"
28
- > end
29
- > end
30
- >
31
- > # add a row
32
- > ret = table.input(:state => "Nebraska", :two_letter_abbrev => "NE")
33
- >
34
- > # get a row object from resp
35
- > subject_key = ret["subjectKey"]
36
- > row = Factual::Row.new(table, subject_key)
37
- > puts row["state"].value
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
@@ -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, @filters, @sorts, 1)
137
- row_data = resp["data", 0]
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.unshift
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, @filters, @sorts, @page_size, @page)
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.unshift
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+1]
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+1])
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
- :fieldId => @field['id'],
297
- :value => value
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, filters=nil, sorts=nil, page_size=nil, page=nil)
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}" + filters_query.to_s + sorts_query.to_s
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{ |k,v| CGI.escape(k.to_s) + '=' + CGI.escape(v.to_json) }.join('&')
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
@@ -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
 
@@ -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["state"].value, "California"
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
- hash: 29
5
- prerelease: false
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-03-30 00:00:00 +08:00
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.3.7
69
+ rubygems_version: 1.6.2
87
70
  signing_key:
88
71
  specification_version: 3
89
72
  summary: ""