rfql 0.1.alpha
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +2 -0
- data/CHANGELOG +1 -0
- data/LICENSE +21 -0
- data/Manifest +20 -0
- data/README.rdoc +14 -0
- data/Rakefile +19 -0
- data/lib/rfql.rb +12 -0
- data/lib/rfql/core_ext/object/blank.rb +10 -0
- data/lib/rfql/query.rb +29 -0
- data/lib/rfql/query/methods.rb +148 -0
- data/lib/rfql/query/quoting.rb +39 -0
- data/lib/rfql/request.rb +92 -0
- data/lib/rfql/request/delegations.rb +11 -0
- data/lib/rfql/response.rb +29 -0
- data/lib/rfql/response/fql_error.rb +10 -0
- data/lib/rfql/response/json.rb +22 -0
- data/lib/rfql/response/json/parsed.rb +26 -0
- data/lib/rfql/response/json/parsed/error.rb +23 -0
- data/lib/rfql/response/json/parsed/null.rb +9 -0
- data/lib/rfql/response/json/parsed/records.rb +15 -0
- data/lib/rfql/response/json/raw.rb +14 -0
- data/rfql.gemspec +31 -0
- metadata +131 -0
- metadata.gz.sig +3 -0
data.tar.gz.sig
ADDED
data/CHANGELOG
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
v0.1.alpha. WIP
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2011 Maurizio De Santis <desantis.maurizio at gmail.com>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/Manifest
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
CHANGELOG
|
2
|
+
LICENSE
|
3
|
+
Manifest
|
4
|
+
README.rdoc
|
5
|
+
Rakefile
|
6
|
+
lib/rfql.rb
|
7
|
+
lib/rfql/core_ext/object/blank.rb
|
8
|
+
lib/rfql/query.rb
|
9
|
+
lib/rfql/query/methods.rb
|
10
|
+
lib/rfql/query/quoting.rb
|
11
|
+
lib/rfql/request.rb
|
12
|
+
lib/rfql/request/delegations.rb
|
13
|
+
lib/rfql/response.rb
|
14
|
+
lib/rfql/response/fql_error.rb
|
15
|
+
lib/rfql/response/json.rb
|
16
|
+
lib/rfql/response/json/parsed.rb
|
17
|
+
lib/rfql/response/json/parsed/error.rb
|
18
|
+
lib/rfql/response/json/parsed/null.rb
|
19
|
+
lib/rfql/response/json/parsed/records.rb
|
20
|
+
lib/rfql/response/json/raw.rb
|
data/README.rdoc
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
= RFQL - Ruby interface for Facebook Query Language
|
2
|
+
|
3
|
+
Work In Progress
|
4
|
+
|
5
|
+
== TODO
|
6
|
+
|
7
|
+
* Implement XML fetching
|
8
|
+
* A bit of refactoring (commenting, move thing up and down and all around...)
|
9
|
+
* Have I implemented errors managing before??? Who knows!
|
10
|
+
* ADD TESTS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
11
|
+
|
12
|
+
== License
|
13
|
+
|
14
|
+
MIT (see LICENSE)
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'psych'
|
2
|
+
require 'echoe'
|
3
|
+
|
4
|
+
Echoe.new("rfql") do |p|
|
5
|
+
p.project = 'ProGNOMmers'
|
6
|
+
p.author = "De Santis Maurizio"
|
7
|
+
p.email = 'desantis.maurizio@gmail.com'
|
8
|
+
p.description = "RFQL - Ruby interface for Facebook Query Language"
|
9
|
+
p.summary = "It lets you use ORM-style code for fetching data from Facebook through the Facebook Query Language"
|
10
|
+
end
|
11
|
+
|
12
|
+
#task :default => :irb
|
13
|
+
task :irb do
|
14
|
+
$LOAD_PATH << "#{Dir.pwd}/lib"
|
15
|
+
require 'rfql'
|
16
|
+
require 'irb'
|
17
|
+
ARGV.clear
|
18
|
+
IRB.start
|
19
|
+
end
|
data/lib/rfql.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rfql/query'
|
2
|
+
require 'rfql/request'
|
3
|
+
module RFQL
|
4
|
+
VERSION = '0.1.alpha'
|
5
|
+
FQLURL = "https://api.facebook.com/method/fql.query"
|
6
|
+
def self.request(obj = nil)
|
7
|
+
RFQL::Request.new(obj)
|
8
|
+
end
|
9
|
+
def self.query(obj = nil)
|
10
|
+
RFQL::Query.new(obj)
|
11
|
+
end
|
12
|
+
end
|
data/lib/rfql/query.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module RFQL
|
2
|
+
class Query < String
|
3
|
+
VALID_QUERY_METHODS = [:select, :from, :where, :order, :limit]
|
4
|
+
def initialize(obj = '')
|
5
|
+
if obj.is_a?(Hash)
|
6
|
+
obj.each do |k, v|
|
7
|
+
if VALID_QUERY_METHODS.include?(k)
|
8
|
+
self.send(k, v)
|
9
|
+
else
|
10
|
+
raise ArgumentError, "hash keys expected to be included in #{VALID_QUERY_METHODS}; got #{k.inspect}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
super(to_s)
|
14
|
+
else
|
15
|
+
@query = obj.to_s
|
16
|
+
end
|
17
|
+
end
|
18
|
+
def to_s
|
19
|
+
@query.present? ? @query.to_s : compose_query
|
20
|
+
end
|
21
|
+
def inspect
|
22
|
+
to_s.inspect
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# This is here in order to avoid conflicts between the RFQL::Query declarations
|
28
|
+
require 'rfql/query/methods'
|
29
|
+
RFQL::Query.send(:include, RFQL::Query::Methods)
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'rfql/query/quoting'
|
2
|
+
module RFQL::Query::Methods
|
3
|
+
include RFQL::Query::Quoting
|
4
|
+
|
5
|
+
def query(query = nil)
|
6
|
+
@query = query
|
7
|
+
self
|
8
|
+
end
|
9
|
+
|
10
|
+
def select(*fields)
|
11
|
+
@select =
|
12
|
+
if fields.blank?
|
13
|
+
nil
|
14
|
+
else
|
15
|
+
fields.flatten!; fields.uniq!; fields.join(', ')
|
16
|
+
end
|
17
|
+
self
|
18
|
+
end
|
19
|
+
def select?; @select; end
|
20
|
+
|
21
|
+
def from(from = nil)
|
22
|
+
@from = from
|
23
|
+
self
|
24
|
+
end
|
25
|
+
def from?; @from; end
|
26
|
+
|
27
|
+
def where(where = nil)
|
28
|
+
@where =
|
29
|
+
case where
|
30
|
+
when String then where
|
31
|
+
when Array then sanitize_sql_array(where)
|
32
|
+
when Hash then sanitize_sql_hash_for_conditions(where)
|
33
|
+
when NilClass then nil
|
34
|
+
else raise ArgumentError, "only strings, hashes or arrays can be converted to sql conditions"
|
35
|
+
end
|
36
|
+
self
|
37
|
+
end
|
38
|
+
def where?; @where; end
|
39
|
+
|
40
|
+
def order(order = nil)
|
41
|
+
@order = order
|
42
|
+
self
|
43
|
+
end
|
44
|
+
def order?; @order; end
|
45
|
+
|
46
|
+
def limit(limit = nil)
|
47
|
+
@limit = limit
|
48
|
+
self
|
49
|
+
end
|
50
|
+
def limit?; @limit; end
|
51
|
+
|
52
|
+
private
|
53
|
+
def compose_query
|
54
|
+
[].tap do |arr|
|
55
|
+
arr << "SELECT #{@select}" if @select.present?
|
56
|
+
arr << "FROM #{@from}" if @from.present?
|
57
|
+
arr << "WHERE #{@where}" if @where.present?
|
58
|
+
arr << "ORDER BY #{@order}" if @order.present?
|
59
|
+
arr << "LIMIT #{@limit}" if @limit.present?
|
60
|
+
end.join(' ')
|
61
|
+
end
|
62
|
+
|
63
|
+
def sanitize_sql_hash_for_conditions(attrs)
|
64
|
+
conditions = attrs.map do |attr, value|
|
65
|
+
attr = attr.to_s
|
66
|
+
attribute_condition(attr, value)
|
67
|
+
end.join(' AND ')
|
68
|
+
|
69
|
+
replace_bind_variables(conditions, expand_range_bind_variables(attrs.values))
|
70
|
+
end
|
71
|
+
|
72
|
+
def attribute_condition(quoted_column_name, argument)
|
73
|
+
case argument
|
74
|
+
when nil then "#{quoted_column_name} IS ?"
|
75
|
+
when Array then "#{quoted_column_name} IN (?)"
|
76
|
+
when Range then if argument.exclude_end?
|
77
|
+
"#{quoted_column_name} >= ? AND #{quoted_column_name} < ?"
|
78
|
+
else
|
79
|
+
"#{quoted_column_name} BETWEEN ? AND ?"
|
80
|
+
end
|
81
|
+
else "#{quoted_column_name} = ?"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def expand_range_bind_variables(bind_vars)
|
86
|
+
expanded = []
|
87
|
+
|
88
|
+
bind_vars.each do |var|
|
89
|
+
next if var.is_a?(Hash)
|
90
|
+
|
91
|
+
if var.is_a?(Range)
|
92
|
+
expanded << var.first
|
93
|
+
expanded << var.last
|
94
|
+
else
|
95
|
+
expanded << var
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
expanded
|
100
|
+
end
|
101
|
+
|
102
|
+
def sanitize_sql_array(ary)
|
103
|
+
statement, *values = ary
|
104
|
+
if values.first.is_a?(Hash) and statement =~ /:\w+/
|
105
|
+
replace_named_bind_variables(statement, values.first)
|
106
|
+
elsif statement.include?('?')
|
107
|
+
replace_bind_variables(statement, values)
|
108
|
+
else
|
109
|
+
statement % values.collect { |value| quote_string(value.to_s) }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def replace_named_bind_variables(statement, bind_vars)
|
114
|
+
statement.gsub(/(:?):([a-zA-Z]\w*)/) do
|
115
|
+
if $1 == ':' # skip postgresql casts
|
116
|
+
$& # return the whole match
|
117
|
+
elsif bind_vars.include?(match = $2.to_sym)
|
118
|
+
quote_bound_value(bind_vars[match])
|
119
|
+
else
|
120
|
+
raise ArgumentError, "missing value for :#{match} in #{statement}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def quote_bound_value(value)
|
126
|
+
if value.respond_to?(:map) && !value.acts_like?(:string)
|
127
|
+
if value.respond_to?(:empty?) && value.empty?
|
128
|
+
quote(nil)
|
129
|
+
else
|
130
|
+
value.map { |v| quote(v) }.join(',')
|
131
|
+
end
|
132
|
+
else
|
133
|
+
quote(value)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def replace_bind_variables(statement, values)
|
138
|
+
raise_if_bind_arity_mismatch(statement, statement.count('?'), values.size)
|
139
|
+
bound = values.dup
|
140
|
+
statement.gsub('?') { quote_bound_value(bound.shift) }
|
141
|
+
end
|
142
|
+
|
143
|
+
def raise_if_bind_arity_mismatch(statement, expected, provided)
|
144
|
+
unless expected == provided
|
145
|
+
raise ArgumentError, "wrong number of bind variables (#{provided} for #{expected}) in: #{statement}"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Adapted from https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
|
2
|
+
require 'yaml'
|
3
|
+
module RFQL
|
4
|
+
class Query
|
5
|
+
module Quoting
|
6
|
+
# Quotes the column value to help prevent
|
7
|
+
# {SQL injection attacks}[http://en.wikipedia.org/wiki/SQL_injection].
|
8
|
+
def quote(value)
|
9
|
+
case value
|
10
|
+
when String then "'#{quote_string(value)}'"
|
11
|
+
when true then 'true'
|
12
|
+
when false then 'false'
|
13
|
+
when nil then "NULL"
|
14
|
+
when Numeric then value.to_s
|
15
|
+
when Date then value.to_time.to_i.to_s
|
16
|
+
when Time then value.to_i.to_s
|
17
|
+
when Symbol then value.to_s
|
18
|
+
else "'#{quote_string(YAML.dump(value))}'"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Quotes a string, escaping any ' (single quote) and \ (backslash)
|
23
|
+
# characters.
|
24
|
+
def quote_string(s)
|
25
|
+
s.gsub(/\\/, '\&\&').gsub(/'/, "''") # ' (for ruby-mode)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Quotes the column name. Defaults to no quoting.
|
29
|
+
def quote_column_name(column_name)
|
30
|
+
column_name.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
# Quotes the table name. Defaults to column name quoting.
|
34
|
+
def quote_table_name(table_name)
|
35
|
+
quote_column_name(table_name)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/rfql/request.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'rfql/core_ext/object/blank'
|
2
|
+
require 'rfql/query'
|
3
|
+
require 'rfql/request/delegations'
|
4
|
+
require 'rfql/response'
|
5
|
+
|
6
|
+
module RFQL
|
7
|
+
class Request
|
8
|
+
include RFQL::Request::QueryMethodsDelegations
|
9
|
+
|
10
|
+
attr_reader :response
|
11
|
+
|
12
|
+
def initialize(str = nil)
|
13
|
+
@query = RFQL::Query.new(str)
|
14
|
+
@format_param = :json
|
15
|
+
end
|
16
|
+
|
17
|
+
def query(query = nil)
|
18
|
+
return @query if query.nil?
|
19
|
+
@query = RFQL::Query.new(query)
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_sql
|
24
|
+
@query.to_s
|
25
|
+
end
|
26
|
+
|
27
|
+
def access_token(access_token = nil)
|
28
|
+
return @access_token if access_token.nil?
|
29
|
+
@access_token = access_token
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def format_param(format_param = nil)
|
34
|
+
return @format_param if format_param.nil?
|
35
|
+
raise ArgumentError, "illegal format" unless [:json, :xml].include?(format_param)
|
36
|
+
@format_param = format_param
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def params(with_format_param = false)
|
41
|
+
params = {:query => to_sql, :access_token => access_token}
|
42
|
+
return params unless with_format_param
|
43
|
+
params.merge(:format => @format_param)
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_url(with_format_param = false)
|
47
|
+
RFQL::FQLURL + '?' + hash_to_params_string(params(with_format_param))
|
48
|
+
end
|
49
|
+
|
50
|
+
def hash_to_params_string(params)
|
51
|
+
params.to_a.select do |param|
|
52
|
+
param[0].present? and param[1].present?
|
53
|
+
end.map do |param|
|
54
|
+
k, v = URI.escape(param[0].to_s), URI.escape(param[1].to_s)
|
55
|
+
k.gsub!('&', '%26'); k.gsub!('=', '%3D'); v.gsub!('&', '%26'); v.gsub!('=', '%3D')
|
56
|
+
"#{k}=#{v}"
|
57
|
+
end.join('&')
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_json(json_format = :parsed, options = {})
|
61
|
+
begin
|
62
|
+
to_json!(json_format, options)
|
63
|
+
rescue RFQL::Response::FQLError
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_json!(json_format = :parsed, options = {})
|
69
|
+
raise ArgumentError, "illegal format" unless [:raw, :parsed].include?(json_format)
|
70
|
+
unless options.is_a?(Hash) and (options.keys - [:open_uri_options, :json_parse_options, :force_execution]).blank?
|
71
|
+
raise ArgumentError, "illegal options"
|
72
|
+
end
|
73
|
+
|
74
|
+
if options.delete(:force_execution).blank? and @response and
|
75
|
+
( ( json_format == :parsed and ( @response.is_a?(RFQL::Response::JSON::Parsed) or
|
76
|
+
@response.is_a?(RFQL::Response::JSON::Parsed::Records) or
|
77
|
+
@response.is_a?(RFQL::Response::JSON::Parsed::Error) ) ) or
|
78
|
+
( json_format == :raw and @response.is_a?(RFQL::Response::JSON::Raw) ) )
|
79
|
+
return @response
|
80
|
+
end
|
81
|
+
|
82
|
+
json_parse_opts = options[:json_parse_options] || {}
|
83
|
+
open_uri_read_opts = options[:open_uri_options] || {}
|
84
|
+
|
85
|
+
@response = RFQL::Response::JSON.new(self, options.merge(:format => json_format))
|
86
|
+
|
87
|
+
raise RFQL::Response::FQLError.new(@response) if @response.is_a?(RFQL::Response::JSON::Parsed::Error)
|
88
|
+
|
89
|
+
@response
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module RFQL
|
2
|
+
class Request
|
3
|
+
module QueryMethodsDelegations
|
4
|
+
def select(*fields); query.select(*fields); self; end
|
5
|
+
def from(from = nil); query.from(from); self; end
|
6
|
+
def where(where = nil); query.where(where); self; end
|
7
|
+
def order(order = nil); query.order(order); self; end
|
8
|
+
def limit(limit = nil); query.limit(limit); self; end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
|
3
|
+
require 'rfql/response/json'
|
4
|
+
require 'rfql/response/fql_error'
|
5
|
+
|
6
|
+
module RFQL
|
7
|
+
module Response
|
8
|
+
class << self
|
9
|
+
def new(request, options = {})
|
10
|
+
options[:format] ||= :json_parsed
|
11
|
+
raise ArgumentError, 'illegal format' unless [:xml, :json_raw, :json_parsed].include?(options[:format])
|
12
|
+
|
13
|
+
case options[:format]
|
14
|
+
when :json_raw, :json_parsed
|
15
|
+
options[:format] = options[:format] == :json_raw ? :raw : :parsed
|
16
|
+
RFQL::Response::JSON.new(request, options)
|
17
|
+
when :xml
|
18
|
+
raise NotImplementedError, 'xml fetching is still a WIP :-P'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
def read(request, options = {})
|
22
|
+
request_url = request.respond_to?(:to_url) ? request.to_url : request.to_s
|
23
|
+
raise ArgumentError, 'illegal format' unless [:xml, :json].include?(options[:format])
|
24
|
+
request_url << "&format=#{options[:format]}"
|
25
|
+
URI.parse(request_url).read(options[:open_uri_options] || {})
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'rfql/response/json/raw'
|
3
|
+
require 'rfql/response/json/parsed'
|
4
|
+
require 'rfql/response/json/parsed/records'
|
5
|
+
require 'rfql/response/json/parsed/null'
|
6
|
+
require 'rfql/response/json/parsed/error'
|
7
|
+
|
8
|
+
module RFQL
|
9
|
+
module Response
|
10
|
+
class JSON
|
11
|
+
def self.new(request, options = {})
|
12
|
+
options[:format] ||= :parsed
|
13
|
+
raise ArgumentError, 'illegal format' unless [:raw, :parsed].include?(options[:format])
|
14
|
+
|
15
|
+
case options[:format]
|
16
|
+
when :raw then RFQL::Response::JSON::Raw.new(request, options)
|
17
|
+
when :parsed then RFQL::Response::JSON::Parsed.new(request, options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module RFQL
|
2
|
+
module Response
|
3
|
+
class JSON
|
4
|
+
class Parsed
|
5
|
+
attr_reader :request, :response
|
6
|
+
def self.new(request, options = {})
|
7
|
+
json_raw_response = RFQL::Response::JSON::Raw.new(request, options)
|
8
|
+
|
9
|
+
json_parsed_response = ::JSON.parse(json_raw_response, options[:json_parse_options] || {})
|
10
|
+
|
11
|
+
if json_parsed_response.is_a?(Hash) and json_parsed_response.has_key?('error_code')
|
12
|
+
RFQL::Response::JSON::Parsed::Error.new(request, json_parsed_response)
|
13
|
+
elsif json_parsed_response.is_a?(Array)
|
14
|
+
RFQL::Response::JSON::Parsed::Records.new(request, json_parsed_response)
|
15
|
+
else
|
16
|
+
super(request, json_parsed_response)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
private
|
20
|
+
def initialize(request, json_parsed_response)
|
21
|
+
@request, @response = request, json_parsed_response
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module RFQL
|
2
|
+
module Response
|
3
|
+
class JSON
|
4
|
+
class Parsed
|
5
|
+
class Error < Hash
|
6
|
+
attr_reader :request
|
7
|
+
def initialize(request, hash)
|
8
|
+
@request = request
|
9
|
+
merge!(hash)
|
10
|
+
# FIXME SyntaxError, dunno why
|
11
|
+
# hash.keys.each do |key|
|
12
|
+
# self.class.class_eval<<-"RB"
|
13
|
+
# def #{key}
|
14
|
+
# send :fetch, #{key}
|
15
|
+
# end
|
16
|
+
# RB
|
17
|
+
# end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module RFQL
|
2
|
+
module Response
|
3
|
+
class JSON
|
4
|
+
class Raw < String
|
5
|
+
attr_reader :request
|
6
|
+
def initialize(request, options = {})
|
7
|
+
@request = request
|
8
|
+
options[:format] = :json
|
9
|
+
super RFQL::Response.read(request, options)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/rfql.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{rfql}
|
5
|
+
s.version = "0.1.alpha"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = [%q{De Santis Maurizio}]
|
9
|
+
s.cert_chain = [%q{/home/mau/.gem_keys/gem-public_cert.pem}]
|
10
|
+
s.date = %q{2011-06-30}
|
11
|
+
s.description = %q{RFQL - Ruby interface for Facebook Query Language}
|
12
|
+
s.email = %q{desantis.maurizio@gmail.com}
|
13
|
+
s.extra_rdoc_files = [%q{CHANGELOG}, %q{LICENSE}, %q{README.rdoc}, %q{lib/rfql.rb}, %q{lib/rfql/core_ext/object/blank.rb}, %q{lib/rfql/query.rb}, %q{lib/rfql/query/methods.rb}, %q{lib/rfql/query/quoting.rb}, %q{lib/rfql/request.rb}, %q{lib/rfql/request/delegations.rb}, %q{lib/rfql/response.rb}, %q{lib/rfql/response/fql_error.rb}, %q{lib/rfql/response/json.rb}, %q{lib/rfql/response/json/parsed.rb}, %q{lib/rfql/response/json/parsed/error.rb}, %q{lib/rfql/response/json/parsed/null.rb}, %q{lib/rfql/response/json/parsed/records.rb}, %q{lib/rfql/response/json/raw.rb}]
|
14
|
+
s.files = [%q{CHANGELOG}, %q{LICENSE}, %q{Manifest}, %q{README.rdoc}, %q{Rakefile}, %q{lib/rfql.rb}, %q{lib/rfql/core_ext/object/blank.rb}, %q{lib/rfql/query.rb}, %q{lib/rfql/query/methods.rb}, %q{lib/rfql/query/quoting.rb}, %q{lib/rfql/request.rb}, %q{lib/rfql/request/delegations.rb}, %q{lib/rfql/response.rb}, %q{lib/rfql/response/fql_error.rb}, %q{lib/rfql/response/json.rb}, %q{lib/rfql/response/json/parsed.rb}, %q{lib/rfql/response/json/parsed/error.rb}, %q{lib/rfql/response/json/parsed/null.rb}, %q{lib/rfql/response/json/parsed/records.rb}, %q{lib/rfql/response/json/raw.rb}, %q{rfql.gemspec}]
|
15
|
+
s.homepage = %q{http://ProGNOMmers.github.com/ProGNOMmers/rfql/}
|
16
|
+
s.rdoc_options = [%q{--line-numbers}, %q{--inline-source}, %q{--title}, %q{Rfql}, %q{--main}, %q{README.rdoc}]
|
17
|
+
s.require_paths = [%q{lib}]
|
18
|
+
s.rubyforge_project = %q{ProGNOMmers}
|
19
|
+
s.rubygems_version = %q{1.8.5}
|
20
|
+
s.signing_key = %q{/home/mau/.gem_keys/gem-private_key.pem}
|
21
|
+
s.summary = %q{It lets you use ORM-style code for fetching data from Facebook through the Facebook Query Language}
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
s.specification_version = 3
|
25
|
+
|
26
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
27
|
+
else
|
28
|
+
end
|
29
|
+
else
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rfql
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.alpha
|
5
|
+
prerelease: 4
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- De Santis Maurizio
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain:
|
12
|
+
- ! '-----BEGIN CERTIFICATE-----
|
13
|
+
|
14
|
+
MIIDRDCCAiygAwIBAgIBADANBgkqhkiG9w0BAQUFADBIMRowGAYDVQQDDBFkZXNh
|
15
|
+
|
16
|
+
bnRpcy5tYXVyaXppbzEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPy
|
17
|
+
|
18
|
+
LGQBGRYDY29tMB4XDTExMDYzMDExMjIyOVoXDTEyMDYyOTExMjIyOVowSDEaMBgG
|
19
|
+
|
20
|
+
A1UEAwwRZGVzYW50aXMubWF1cml6aW8xFTATBgoJkiaJk/IsZAEZFgVnbWFpbDET
|
21
|
+
|
22
|
+
MBEGCgmSJomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
23
|
+
|
24
|
+
ggEBANa1yrC8nNkg8hfVU5LNqgh6WwaXSh6tGPn6V0XtMIyMiHF1ess24NPQqPpl
|
25
|
+
|
26
|
+
43t4hWOEGrcfwmnQso1sJsK+TiQ29dyC9upfRz4H0BxzIUUQNQae2F1d2BfptnUg
|
27
|
+
|
28
|
+
xPFPBhBztkpL9I6O1MeZn8zyCczqEHwV18dwbeLssxbJLloVEIpVQFvOI6DSZB1r
|
29
|
+
|
30
|
+
v4T8EieG79jsS2pf2yK9gWuyTnxq27RlTQxHghC0Xnu79b8TrUkiJt8sbjgGP2Ax
|
31
|
+
|
32
|
+
g08RtZP/owHzNWgLCT4exO68gEnRct/34ju0VL7zaG7TbA1cUFBWEtDR/YQw06+x
|
33
|
+
|
34
|
+
LseG3fuRWZIuENeXUJFLUkLF/Z8CAwEAAaM5MDcwCQYDVR0TBAIwADAdBgNVHQ4E
|
35
|
+
|
36
|
+
FgQUcbnTN20o+PJYFy32iMllDe8CuE0wCwYDVR0PBAQDAgSwMA0GCSqGSIb3DQEB
|
37
|
+
|
38
|
+
BQUAA4IBAQBCkfsLuziCNp2uBRWwyr4b0/Yct172ftsAcgGQilVkaGx3VYu9G3WZ
|
39
|
+
|
40
|
+
uxLoofO1c1pgvPqbjLAKq0EUqLxna54ILER6WVaPk70RtIQc2d3Rkj7CEpTI+veW
|
41
|
+
|
42
|
+
ki7IL2OzjVD5Mxad5PEEyCLWrC5Ky2I8OqP8HfwnG0a19YfZRhxAH9XOkQX5HB3O
|
43
|
+
|
44
|
+
t7xlgHGYIHKHfIFCo3UZfaqn354vtbetA0Omt52ZHjt88PsVG0rTrovNctkh61Vq
|
45
|
+
|
46
|
+
99PUQdKGcIRcEsw4zQN3XgwJEqRVV5F6gGQyUY2LIeyyf+58kuHL2UkpVJU7b+7d
|
47
|
+
|
48
|
+
1qFkvs/eJXM+w3TkQ2vaW9KFXQkIewZs
|
49
|
+
|
50
|
+
-----END CERTIFICATE-----
|
51
|
+
|
52
|
+
'
|
53
|
+
date: 2011-06-30 00:00:00.000000000Z
|
54
|
+
dependencies: []
|
55
|
+
description: RFQL - Ruby interface for Facebook Query Language
|
56
|
+
email: desantis.maurizio@gmail.com
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files:
|
60
|
+
- CHANGELOG
|
61
|
+
- LICENSE
|
62
|
+
- README.rdoc
|
63
|
+
- lib/rfql.rb
|
64
|
+
- lib/rfql/core_ext/object/blank.rb
|
65
|
+
- lib/rfql/query.rb
|
66
|
+
- lib/rfql/query/methods.rb
|
67
|
+
- lib/rfql/query/quoting.rb
|
68
|
+
- lib/rfql/request.rb
|
69
|
+
- lib/rfql/request/delegations.rb
|
70
|
+
- lib/rfql/response.rb
|
71
|
+
- lib/rfql/response/fql_error.rb
|
72
|
+
- lib/rfql/response/json.rb
|
73
|
+
- lib/rfql/response/json/parsed.rb
|
74
|
+
- lib/rfql/response/json/parsed/error.rb
|
75
|
+
- lib/rfql/response/json/parsed/null.rb
|
76
|
+
- lib/rfql/response/json/parsed/records.rb
|
77
|
+
- lib/rfql/response/json/raw.rb
|
78
|
+
files:
|
79
|
+
- CHANGELOG
|
80
|
+
- LICENSE
|
81
|
+
- Manifest
|
82
|
+
- README.rdoc
|
83
|
+
- Rakefile
|
84
|
+
- lib/rfql.rb
|
85
|
+
- lib/rfql/core_ext/object/blank.rb
|
86
|
+
- lib/rfql/query.rb
|
87
|
+
- lib/rfql/query/methods.rb
|
88
|
+
- lib/rfql/query/quoting.rb
|
89
|
+
- lib/rfql/request.rb
|
90
|
+
- lib/rfql/request/delegations.rb
|
91
|
+
- lib/rfql/response.rb
|
92
|
+
- lib/rfql/response/fql_error.rb
|
93
|
+
- lib/rfql/response/json.rb
|
94
|
+
- lib/rfql/response/json/parsed.rb
|
95
|
+
- lib/rfql/response/json/parsed/error.rb
|
96
|
+
- lib/rfql/response/json/parsed/null.rb
|
97
|
+
- lib/rfql/response/json/parsed/records.rb
|
98
|
+
- lib/rfql/response/json/raw.rb
|
99
|
+
- rfql.gemspec
|
100
|
+
homepage: http://ProGNOMmers.github.com/ProGNOMmers/rfql/
|
101
|
+
licenses: []
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options:
|
104
|
+
- --line-numbers
|
105
|
+
- --inline-source
|
106
|
+
- --title
|
107
|
+
- Rfql
|
108
|
+
- --main
|
109
|
+
- README.rdoc
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
120
|
+
requirements:
|
121
|
+
- - ! '>='
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '1.2'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project: ProGNOMmers
|
126
|
+
rubygems_version: 1.8.5
|
127
|
+
signing_key:
|
128
|
+
specification_version: 3
|
129
|
+
summary: It lets you use ORM-style code for fetching data from Facebook through the
|
130
|
+
Facebook Query Language
|
131
|
+
test_files: []
|
metadata.gz.sig
ADDED