Class: Factual::Table

Inherits:
Object
  • Object
show all
Defined in:
lib/factual.rb

Overview

This class holds the metadata of a Factual table. The filter and sort methods are to filter and/or sort the table data before calling a find_one or each_row.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(table_key, adapter) ⇒ Table

:nodoc:



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/factual.rb', line 58

def initialize(table_key, adapter) # :nodoc:
  @table_key = table_key
  @adapter   = adapter
  @schema    = adapter.schema(@table_key)
  @key       = table_key
  @page_size = Adapter::DEFAULT_LIMIT
  @page      = 1

 [:name, :description, :rating, :source, :creator, :total_row_count, :created_at, :updated_at, :fields, :geo_enabled, :downloadable].each do |attr|
   k = camelize(attr)
   self.send("#{attr}=", @schema[k]) 
 end

 @fields_lookup = {}
 @fields.each do |f|
   fid = f['id']
   field_ref = @schema["fieldRefs"][fid.to_s]
   f['field_ref'] = field_ref
   @fields_lookup[field_ref] = f
 end
end

Instance Attribute Details

#adapterObject (readonly)

:nodoc:



56
57
58
# File 'lib/factual.rb', line 56

def adapter
  @adapter
end

#created_atObject

Returns the value of attribute created_at.



54
55
56
# File 'lib/factual.rb', line 54

def created_at
  @created_at
end

#creatorObject

Returns the value of attribute creator.



54
55
56
# File 'lib/factual.rb', line 54

def creator
  @creator
end

#descriptionObject

Returns the value of attribute description.



54
55
56
# File 'lib/factual.rb', line 54

def description
  @description
end

#downloadableObject

Returns the value of attribute downloadable.



54
55
56
# File 'lib/factual.rb', line 54

def downloadable
  @downloadable
end

#fieldsObject

Returns the value of attribute fields.



54
55
56
# File 'lib/factual.rb', line 54

def fields
  @fields
end

#geo_enabledObject

Returns the value of attribute geo_enabled.



54
55
56
# File 'lib/factual.rb', line 54

def geo_enabled
  @geo_enabled
end

#keyObject

Returns the value of attribute key.



54
55
56
# File 'lib/factual.rb', line 54

def key
  @key
end

#nameObject

Returns the value of attribute name.



54
55
56
# File 'lib/factual.rb', line 54

def name
  @name
end

#page(page_num, page_size_hash = nil) ⇒ Object

Define the paging, it can be chained before find_one or each_row, each_row makes more sense though. The default page size is 20. And there is a API limitation policy need to be followed.

The params are:

  • page_num: the page number

  • page_size_hash (optional): { :size => <page_size> }

Samples:

table.page(2).each_row { |row| ... } # for each row of the 2nd page
table.page(2, :size => 10).each_row { |row| ... } # for each row of the 2nd page, when page size is 10


90
91
92
# File 'lib/factual.rb', line 90

def page
  @page
end

#page_sizeObject

Returns the value of attribute page_size.



55
56
57
# File 'lib/factual.rb', line 55

def page_size
  @page_size
end

#ratingObject

Returns the value of attribute rating.



54
55
56
# File 'lib/factual.rb', line 54

def rating
  @rating
end

#sourceObject

Returns the value of attribute source.



54
55
56
# File 'lib/factual.rb', line 54

def source
  @source
end

#total_row_countObject

Returns the value of attribute total_row_count.



54
55
56
# File 'lib/factual.rb', line 54

def total_row_count
  @total_row_count
end

#updated_atObject

Returns the value of attribute updated_at.



54
55
56
# File 'lib/factual.rb', line 54

def updated_at
  @updated_at
end

Instance Method Details

#each_rowObject

An iterator on each row (a Factual::Row object) of the filtered and/or sorted table data

Samples:

table.filter(:state => 'CA').search('starbucks').sort(:city => 1).each do |row|
  puts row.inspect
end


172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/factual.rb', line 172

def each_row
  resp = @adapter.read_table(@table_key, 
      :filters   => @filters, 
      :searches  => @searches, 
      :sorts     => @sorts, 
      :page_size => @page_size, 
      :page      => @page)

  @total_rows = resp["total_rows"]
  rows = resp["data"]

  rows.each do |row_data|
    subject_key = row_data.shift
    row = Row.new(self, subject_key, row_data) 
    yield(row) if block_given?
  end
end

#filter(filters) ⇒ Object

Define table filters, it can be chained before find_one or each_row.

The params can be:

  • simple hash for equal filter

  • nested hash with filter operators

Samples:

table.filter(:state => 'CA').find_one # hash
table.filter(:state => 'CA', :city => 'LA').find_one # multi-key hash
table.filter(:state => {"$has" => 'A'}).find_one  # nested hash
table.filter(:state => {"$has" => 'A'}, :city => {"$ew" => 'A'}).find_one # multi-key nested hashes

For more detail inforamtion about filter syntax, please look up at Server API Doc for Filter



124
125
126
127
# File 'lib/factual.rb', line 124

def filter(filters)
  @filters = filters
  return self
end

#find_oneObject

Find the first row (a Factual::Row object) of the table with filters and/or sorts.

Samples:

  • table.filter(:state => 'CA').find_one

  • table.filter(:state => 'CA').sort(:city => 1).find_one

  • table.filter(:state => 'CA').search('starbucks').sort(:city => 1).find_one



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/factual.rb', line 150

def find_one
  resp = @adapter.read_table(@table_key, 
      :filters   => @filters, 
      :searches  => @searches, 
      :sorts     => @sorts, 
      :page_size => 1)
  row_data = resp["data"].first

  if row_data.is_a?(Array)
    subject_key = row_data.shift
    return Row.new(self, subject_key, row_data)
  else
    return nil
  end
end

#input(values_hash, opts = {}) ⇒ Object

Suggest values for a row, it can be used to create a row, or edit an existing row

Parameters:

* +values_hash+ 
* values in hash, field_refs as keys
* +opts+ 
* <tt>opts[:source]</tt> the source of an input, can be a URL or something else
* <tt>opts[:comments]</tt> the comments of an input

Returns:

{ "subjectKey" => <subject_key>, "exists" => <true|false> }
subjectKey: a Factual::Row object can be initialized by a subjectKey, e.g. Factual::Row.new(@table, subject_key)
exists: if "exists" is true, it means an existing row is edited, otherwise, a new row added

Sample:

table.input :two_letter_abbrev => 'NE', :state => 'Nebraska'
table.input({:two_letter_abbrev => 'NE', :state => 'Nebraska'}, {:source => 'http://website.com', :comments => 'cornhusker!'})


207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/factual.rb', line 207

def input(values_hash, opts={})
  values = values_hash.collect do |field_ref, value|
    field = @fields_lookup[field_ref.to_s]
    raise Factual::ArgumentError.new("Wrong field ref.") unless field
    
    { :fieldId => field['id'], :value => value}
  end

  hash = opts.merge({ :values => values })

  ret = @adapter.input(@table_key, hash)
  return ret
end

#input_with_token(token, values_hash, opts = {}) ⇒ Object

Suggest values for a row with a token, it is similar to input, but merely for shadow accounts input, it is a parter-only feature.

Parameters:

* +token+ 
* +values_hash+ 
* +opts+

Returns:

{ "subjectKey" => <subject_key>, "exists" => <true|false> }
subjectKey: a Factual::Row object can be initialized by a subjectKey, e.g. Factual::Row.new(@table, subject_key)
exists: if "exists" is true, it means an existing row is edited, otherwise, a new row added

Sample:

table.input "8kTXTBWBpNFLybFiDmApS9pnQyw2YkM4qImH2XpbC6AG1ixkZFCKKbx2Jk0cGl8Z", :two_letter_abbrev => 'NE', :state => 'Nebraska'
table.input("8kTXTBWBpNFLybFiDmApS9pnQyw2YkM4qImH2XpbC6AG1ixkZFCKKbx2Jk0cGl8Z", {:two_letter_abbrev => 'NE', :state => 'Nebraska'}, {:source => 'http://website.com', :comments => 'cornhusker!'})


236
237
238
# File 'lib/factual.rb', line 236

def input_with_token(token, values_hash, opts={})
  return input(values_hash, opts.merge({ :token => token }))
end

#search(*queries) ⇒ Object

Define table search queries, it can be chained before find_one or each_row.

The params can be:

  • A query string

  • An array of query strings

Samples:

table.serach('starbucks').find_one # one query
table.search('starbucks', 'burger king').find_one # multiple queries


106
107
108
109
# File 'lib/factual.rb', line 106

def search(*queries)
  @searches = queries
  return self
end

#sort(*sorts) ⇒ Object

Define table sorts, it can be chained before find_one or each_row.

The params can be:

  • a hash with single key

  • single-key hashes, only the first 2 sorts will work. (secondary sort will be supported in next release of Factual API)

Samples:

table.sort(:state => 1).find_one  # hash with single key
table.sort({:state => 1}, {:abbr => -1}).find_one # single-key hashes

For more detail inforamtion about sort syntax, please look up at Server API Doc for Sort (TODO)



139
140
141
142
# File 'lib/factual.rb', line 139

def sort(*sorts)
  @sorts = sorts
  return self
end