fusion_tables 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ == 0.3.0 (05/06/11)
2
+
3
+ * simple SQL interface API
4
+
5
+ == 0.2.4 (03/06/11)
6
+
7
+ * bugfixes
8
+
1
9
  == 0.2.3 (03/06/11)
2
10
 
3
11
  * all tests pass
data/README.md CHANGED
@@ -1,14 +1,16 @@
1
1
  fusion-tables
2
2
  ==============
3
3
 
4
- This gem lets you easily interact with [Google Fusion Tables](http://www.google.com/fusiontables/Home) from your Ruby application. Read more in this [Blog post](http://www.tokumine.com/2010/08/10/fusion-tables-gem/).
4
+ This gem lets you easily interact with [Google Fusion Tables](http://www.google.com/fusiontables/Home) from your Ruby application. There is a plain SQL interface, or an object orientated interface available.
5
5
 
6
6
  Demo and examples
7
7
  ------------------
8
8
 
9
- * Twitter [demo](http://tables.googlelabs.com/DataSource?snapid=73106) / [code](http://github.com/tokumine/fusion-tables/blob/master/examples/compare_tweets.rb)
10
- * Boris bike [demo](http://tables.googlelabs.com/DataSource?snapid=78314) / [code](http://github.com/tokumine/fusion-tables/blob/master/examples/boris_bikes.rb)
11
- * [Tests](http://github.com/tokumine/fusion-tables/tree/master/test/)
9
+ * Twitter [demo](http://tables.googlelabs.com/DataSource?snapid=73106) / [code](http://github.com/tokumine/fusion_tables/blob/master/examples/compare_tweets.rb) /
10
+ [blog](http://www.tokumine.com/2010/08/10/fusion-tables-gem/)
11
+ * Boris bike [demo](http://tables.googlelabs.com/DataSource?snapid=78314) / [code](http://github.com/tokumine/fusion_tables/blob/master/examples/boris_bikes.rb)
12
+ * [Tests](http://github.com/tokumine/fusion_tables/tree/master/test/)
13
+
12
14
 
13
15
  Installation
14
16
  -------------
@@ -31,10 +33,21 @@ Usage
31
33
  ``` ruby
32
34
  require 'fusion_tables'
33
35
 
36
+
34
37
  # Connect to service
35
38
  @ft = GData::Client::FusionTables.new
36
39
  @ft.clientlogin(username, password)
37
40
 
41
+
42
+ # 1. Simple SQL interface
43
+ # =========================
44
+ @ft.execute "SHOW TABLES"
45
+ @ft.execute "INSERT INTO #{my_table_id} (name, geo) VALUES ('tokyo', '35.6894 139.6917');"
46
+ @ft.execute "SELECT count() FROM #{my_table_id};"
47
+
48
+
49
+ # 2. basic ORM interface
50
+ # ========================
38
51
  # Browse existing tables
39
52
  @ft.show_tables
40
53
  # => [table_1, table_2]
@@ -76,21 +89,17 @@ data = [{"friend name" => "Eric Wimp",
76
89
  "where" => "29 Acacia Road, Nuttytown"}]
77
90
  new_table.insert data
78
91
 
79
- # Delete row
80
- new_table.delete row_id
81
- ```
92
+ # Currently FT API only supports single row UPDATE.
93
+ new_table.update 1, [{"friend name" => "Bananaman"}]
82
94
 
83
- Currently only single row UPDATE query is implemented.
95
+ # Delete row
96
+ new_table.delete 1
84
97
 
85
- ``` ruby
86
- row_id = 1
87
- data = [{"friend name" => "Eric Wimp",
88
- "age" => 25,
89
- "meeting time" => Time.utc(2010,"aug",10,20,15,1),
90
- "where" => "29 Acacia Road, Nuttytown"}]
91
- new_table.update row_id, data
98
+ # Delete all rows
99
+ new_table.truncate!
92
100
  ```
93
101
 
102
+
94
103
  Known Issues
95
104
  -------------
96
105
 
@@ -1,6 +1,13 @@
1
- Areas of improvement:
1
+ Gem
2
+ ====
3
+ * YARD docs
2
4
 
3
- * response format json/xml
5
+
6
+
7
+ API wishlist
8
+ =============
9
+ * Bulk UPDATE
10
+ * response format in json/xml
4
11
  * "create table" should return name
5
12
  * describe table should include name
6
13
  * multiple batch statements for all actions (only insert now). Need on all other commands. Better SQL.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.4
1
+ 0.3.0
@@ -1,60 +1,50 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{fusion_tables}
8
- s.version = "0.2.4"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Simon Tokumine", "Tom Verbeure"]
12
- s.date = %q{2011-06-03}
12
+ s.date = %q{2011-06-05}
13
13
  s.description = %q{A simple Google Fusion Tables API wrapper. Supports bulk inserts and most API functions}
14
14
  s.email = %q{simon@tinypla.net}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
- "README.md",
18
- "TODO"
17
+ "README.md"
19
18
  ]
20
19
  s.files = [
21
20
  ".document",
22
- ".gitignore",
23
- "CHANGELOG",
24
- "LICENSE",
25
- "README.md",
26
- "Rakefile",
27
- "TODO",
28
- "VERSION",
29
- "examples/boris_bikes.rb",
30
- "examples/compare_tweets.rb",
31
- "examples/credentials.example.yml",
32
- "fusion_tables.gemspec",
33
- "lib/fusion_tables.rb",
34
- "lib/fusion_tables/client/fusion_tables.rb",
35
- "lib/fusion_tables/data/data.rb",
36
- "lib/fusion_tables/data/table.rb",
37
- "lib/fusion_tables/ext/fusion_tables.rb",
38
- "test/README",
39
- "test/helper.rb",
40
- "test/test_client.rb",
41
- "test/test_config.yml.sample",
42
- "test/test_ext.rb",
43
- "test/test_table.rb"
21
+ "CHANGELOG",
22
+ "LICENSE",
23
+ "README.md",
24
+ "Rakefile",
25
+ "TODO.md",
26
+ "VERSION",
27
+ "examples/boris_bikes.rb",
28
+ "examples/compare_tweets.rb",
29
+ "examples/credentials.example.yml",
30
+ "fusion_tables.gemspec",
31
+ "lib/fusion_tables.rb",
32
+ "lib/fusion_tables/client/fusion_tables.rb",
33
+ "lib/fusion_tables/data/data.rb",
34
+ "lib/fusion_tables/data/table.rb",
35
+ "lib/fusion_tables/ext/fusion_tables.rb",
36
+ "test/README",
37
+ "test/helper.rb",
38
+ "test/test_client.rb",
39
+ "test/test_config.yml.sample",
40
+ "test/test_ext.rb",
41
+ "test/test_sql.rb",
42
+ "test/test_table.rb"
44
43
  ]
45
44
  s.homepage = %q{http://github.com/tokumine/fusion_tables}
46
- s.rdoc_options = ["--charset=UTF-8"]
47
45
  s.require_paths = ["lib"]
48
- s.rubygems_version = %q{1.4.1}
46
+ s.rubygems_version = %q{1.6.2}
49
47
  s.summary = %q{Google Fusion Tables API wrapper}
50
- s.test_files = [
51
- "test/helper.rb",
52
- "test/test_client.rb",
53
- "test/test_ext.rb",
54
- "test/test_table.rb",
55
- "examples/boris_bikes.rb",
56
- "examples/compare_tweets.rb"
57
- ]
58
48
 
59
49
  if s.respond_to? :specification_version then
60
50
  s.specification_version = 3
@@ -20,28 +20,27 @@ module GData
20
20
  DATATYPES = %w(number string location datetime)
21
21
 
22
22
  def initialize(options = {})
23
- options[:clientlogin_service] ||= 'fusiontables'
24
- options[:headers] = { 'Content-Type' => 'application/x-www-form-urlencoded' }
25
- super(options)
23
+ options[:clientlogin_service] ||= 'fusiontables'
24
+ options[:headers] = { 'Content-Type' => 'application/x-www-form-urlencoded' }
25
+ super(options)
26
26
  end
27
27
 
28
28
  def sql_encode(sql)
29
- "sql=" + CGI::escape(sql)
29
+ "sql=" + CGI::escape(sql)
30
30
  end
31
31
 
32
32
  def sql_get(sql)
33
- resp = self.get(SERVICE_URL + "?" + sql_encode(sql))
33
+ resp = self.get(SERVICE_URL + "?" + sql_encode(sql))
34
34
  end
35
35
 
36
36
  def sql_post(sql)
37
- resp = self.post(SERVICE_URL, sql_encode(sql))
37
+ resp = self.post(SERVICE_URL, sql_encode(sql))
38
38
  end
39
39
 
40
40
  def sql_put(sql)
41
- resp = self.put(SERVICE_URL, sql_encode(sql))
41
+ resp = self.put(SERVICE_URL, sql_encode(sql))
42
42
  end
43
-
44
-
43
+
45
44
  # Overrides auth_handler= so if the authentication changes,
46
45
  # the session cookie is cleared.
47
46
  def auth_handler=(handler)
@@ -30,11 +30,10 @@ module GData
30
30
  @name = options[:name]
31
31
  end
32
32
 
33
-
34
33
  # Sets up data types from google
35
34
  #
36
35
  def describe
37
- GData::Client::FusionTables::Data.parse(@client.sql_get("DESCRIBE #{@id}")).body
36
+ @client.execute "DESCRIBE #{@id}"
38
37
  end
39
38
 
40
39
  # Runs select and returns data obj
@@ -46,8 +45,7 @@ module GData
46
45
  # use columns=ROWID to select row ids
47
46
  #
48
47
  def select columns="*", conditions=nil
49
- sql = "SELECT #{columns} FROM #{@id} #{conditions}"
50
- GData::Client::FusionTables::Data.parse(@client.sql_get(sql)).body
48
+ @client.execute "SELECT #{columns} FROM #{@id} #{conditions}"
51
49
  end
52
50
 
53
51
  # Returns a count of rows. SQL conditions optional
@@ -92,19 +90,17 @@ module GData
92
90
  def update row_id, data
93
91
  data = encode([data]).first
94
92
  data = data.to_a.map{|x| x.join("=")}.join(", ")
95
- sql = "UPDATE #{@id} SET #{data} WHERE ROWID = '#{row_id}'"
96
- GData::Client::FusionTables::Data.parse(@client.sql_post(sql)).body
93
+ @client.execute "UPDATE #{@id} SET #{data} WHERE ROWID = '#{row_id}'"
97
94
  end
98
95
 
99
96
  # delete row
100
97
  def delete row_id
101
- sql = "DELETE FROM #{@id} WHERE rowid='#{row_id}'"
102
- GData::Client::FusionTables::Data.parse(@client.sql_post(sql)).body
98
+ @client.execute "DELETE FROM #{@id} WHERE rowid='#{row_id}'"
103
99
  end
104
100
 
105
101
  # delete all rows
106
102
  def truncate!
107
- GData::Client::FusionTables::Data.parse(@client.sql_post("DELETE FROM #{@id}")).body
103
+ @client.execute "DELETE FROM #{@id}"
108
104
  end
109
105
 
110
106
  def get_headers
@@ -130,7 +126,7 @@ module GData
130
126
  ar
131
127
  end
132
128
  end
133
-
129
+
134
130
  #
135
131
  # Returns datatype of given column name
136
132
  #
@@ -15,16 +15,22 @@
15
15
  module GData
16
16
  module Client
17
17
  class FusionTables < Base
18
+
19
+ # Helper method to run FT SQL and return FT data object
20
+ def execute(sql)
21
+ http_req = sql.upcase.match(/^(DESCRIBE|SHOW|SELECT)/) ? :sql_get : :sql_post
22
+ GData::Client::FusionTables::Data.parse(self.send(http_req, sql)).body
23
+ end
18
24
 
19
25
  # Show a list of fusion tables
20
26
  def show_tables
21
- data = GData::Client::FusionTables::Data.parse(self.sql_get("SHOW TABLES"))
27
+ data = self.execute "SHOW TABLES"
28
+
22
29
  data.inject([]) do |x, row|
23
30
  x << GData::Client::FusionTables::Table.new(self, row)
24
31
  x
25
32
  end
26
33
  end
27
-
28
34
 
29
35
  # Create a new table. Return the corresponding table
30
36
  #
@@ -0,0 +1,80 @@
1
+ require 'helper'
2
+
3
+ class TestTable < Test::Unit::TestCase
4
+
5
+ context "testing plain SQL" do
6
+ setup do
7
+ init_config
8
+ @ft = GData::Client::FusionTables.new
9
+ @ft.clientlogin(username, password)
10
+ @table = @ft.create_table "test", [{:name => 'firstname', :type => 'string'},
11
+ {:name => 'phone', :type => 'number'},
12
+ {:name => 'dob', :type => 'datetime'},
13
+ {:name => 'house', :type => 'location'}]
14
+ end
15
+
16
+ should "be able to SHOW TABLES" do
17
+ ret = @ft.execute "SHOW TABLES"
18
+ assert !ret.empty?
19
+ assert_equal Array, ret.class
20
+ end
21
+
22
+ should "be able to DESCRIBE a table" do
23
+ ret = @ft.execute("DESCRIBE #{@table.id}")
24
+ expected = [{:column_id=>"col0", :name=>"firstname", :type=>"string"},
25
+ {:column_id=>"col1", :name=>"phone", :type=>"number"},
26
+ {:column_id=>"col2", :name=>"dob", :type=>"datetime"},
27
+ {:column_id=>"col3", :name=>"house", :type=>"location"}]
28
+ assert_equal expected, ret
29
+ end
30
+
31
+ should "be able to INSERT a row" do
32
+ ret = @ft.execute "INSERT INTO #{@table.id} (firstname) VALUES ('eric');"
33
+ assert_equal 1, ret.first[:rowid].to_i
34
+ end
35
+
36
+ should "be able to SELECT a row" do
37
+ @ft.execute "INSERT INTO #{@table.id} (firstname) VALUES ('eric');"
38
+ ret = @ft.execute "SELECT ROWID, firstname FROM #{@table.id}"
39
+ assert_equal [{:rowid=>"1", :firstname=>"eric"}], ret
40
+ end
41
+
42
+ should "be able to UPDATE a row" do
43
+ @ft.execute "INSERT INTO #{@table.id} (firstname) VALUES ('eric');"
44
+
45
+ ret = @ft.execute "SELECT ROWID, firstname FROM #{@table.id}"
46
+ assert_equal [{:rowid=>"1", :firstname=>"eric"}], ret
47
+
48
+ ret = @ft.execute "UPDATE #{@table.id} SET firstname='simon' WHERE ROWID = '#{ret.first[:rowid]}'"
49
+ ret = @ft.execute "SELECT ROWID, firstname FROM #{@table.id}"
50
+ assert_equal [{:rowid=>"1", :firstname=>"simon"}], ret
51
+ end
52
+
53
+ should "be able to DELETE a row" do
54
+ @ft.execute "INSERT INTO #{@table.id} (firstname) VALUES ('eric');"
55
+ @ft.execute "INSERT INTO #{@table.id} (firstname) VALUES ('eric');"
56
+
57
+ ret = @ft.execute "SELECT ROWID FROM #{@table.id};"
58
+ @ft.execute "DELETE FROM #{@table.id} WHERE ROWID = '#{ret.first[:rowid]}';"
59
+
60
+ ret = @ft.execute "SELECT count() FROM #{@table.id};"
61
+
62
+ assert_equal 1, ret.first[:"count()"].to_i
63
+ end
64
+
65
+ # should "be able to query geographic data" do
66
+ # @table = @ft.create_table "test", [{:name => 'name', :type => 'string'},
67
+ # {:name => 'geo', :type => 'location'}]
68
+ #
69
+ # @ft.execute "INSERT INTO #{@table.id} (name, geo) VALUES ('tokyo', '35.6894 139.6917');
70
+ # INSERT INTO #{@table.id} (name, geo) VALUES ('osaka', '34.6937 135.5021');
71
+ # INSERT INTO #{@table.id} (name, geo) VALUES ('fukuoka', '33.5903 130.4017');
72
+ # INSERT INTO #{@table.id} (name, geo) VALUES ('kyoto', '35.0116 135.7680');
73
+ # INSERT INTO #{@table.id} (name, geo) VALUES ('nagoya', '35.1814 136.9063');"
74
+ #
75
+ # # get cities nearest to Nara
76
+ # res = @ft.execute "SELECT * FROM #{@table.id} ORDER BY ST_DISTANCE(geo, LATLNG(35.6894,139.6917)) LIMIT 10"
77
+ # puts res.inspect
78
+ # end
79
+ end
80
+ end
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fusion_tables
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
5
4
  prerelease:
6
- segments:
7
- - 0
8
- - 2
9
- - 4
10
- version: 0.2.4
5
+ version: 0.3.0
11
6
  platform: ruby
12
7
  authors:
13
8
  - Simon Tokumine
@@ -16,7 +11,7 @@ autorequire:
16
11
  bindir: bin
17
12
  cert_chain: []
18
13
 
19
- date: 2011-06-03 00:00:00 +01:00
14
+ date: 2011-06-05 00:00:00 +01:00
20
15
  default_executable:
21
16
  dependencies:
22
17
  - !ruby/object:Gem::Dependency
@@ -27,9 +22,6 @@ dependencies:
27
22
  requirements:
28
23
  - - ">="
29
24
  - !ruby/object:Gem::Version
30
- hash: 3
31
- segments:
32
- - 0
33
25
  version: "0"
34
26
  type: :development
35
27
  version_requirements: *id001
@@ -41,11 +33,6 @@ dependencies:
41
33
  requirements:
42
34
  - - ">="
43
35
  - !ruby/object:Gem::Version
44
- hash: 23
45
- segments:
46
- - 1
47
- - 1
48
- - 2
49
36
  version: 1.1.2
50
37
  type: :runtime
51
38
  version_requirements: *id002
@@ -58,15 +45,13 @@ extensions: []
58
45
  extra_rdoc_files:
59
46
  - LICENSE
60
47
  - README.md
61
- - TODO
62
48
  files:
63
49
  - .document
64
- - .gitignore
65
50
  - CHANGELOG
66
51
  - LICENSE
67
52
  - README.md
68
53
  - Rakefile
69
- - TODO
54
+ - TODO.md
70
55
  - VERSION
71
56
  - examples/boris_bikes.rb
72
57
  - examples/compare_tweets.rb
@@ -82,14 +67,15 @@ files:
82
67
  - test/test_client.rb
83
68
  - test/test_config.yml.sample
84
69
  - test/test_ext.rb
70
+ - test/test_sql.rb
85
71
  - test/test_table.rb
86
72
  has_rdoc: true
87
73
  homepage: http://github.com/tokumine/fusion_tables
88
74
  licenses: []
89
75
 
90
76
  post_install_message:
91
- rdoc_options:
92
- - --charset=UTF-8
77
+ rdoc_options: []
78
+
93
79
  require_paths:
94
80
  - lib
95
81
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -97,30 +83,19 @@ required_ruby_version: !ruby/object:Gem::Requirement
97
83
  requirements:
98
84
  - - ">="
99
85
  - !ruby/object:Gem::Version
100
- hash: 3
101
- segments:
102
- - 0
103
86
  version: "0"
104
87
  required_rubygems_version: !ruby/object:Gem::Requirement
105
88
  none: false
106
89
  requirements:
107
90
  - - ">="
108
91
  - !ruby/object:Gem::Version
109
- hash: 3
110
- segments:
111
- - 0
112
92
  version: "0"
113
93
  requirements: []
114
94
 
115
95
  rubyforge_project:
116
- rubygems_version: 1.4.1
96
+ rubygems_version: 1.6.2
117
97
  signing_key:
118
98
  specification_version: 3
119
99
  summary: Google Fusion Tables API wrapper
120
- test_files:
121
- - test/helper.rb
122
- - test/test_client.rb
123
- - test/test_ext.rb
124
- - test/test_table.rb
125
- - examples/boris_bikes.rb
126
- - examples/compare_tweets.rb
100
+ test_files: []
101
+
data/.gitignore DELETED
@@ -1,26 +0,0 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- examples/credentials.yml
20
-
21
- ## PROJECT::TEST
22
- test/test_config.yml
23
-
24
-
25
- ## PROJECT::SPECIFIC
26
-