fusion_tables 0.2.2 → 0.2.3

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/.gitignore CHANGED
@@ -16,9 +16,11 @@ tmtags
16
16
  ## PROJECT::GENERAL
17
17
  coverage
18
18
  rdoc
19
+ examples/credentials.yml
19
20
 
20
21
  ## PROJECT::TEST
21
22
  test/test_config.yml
22
23
 
24
+
23
25
  ## PROJECT::SPECIFIC
24
26
 
data/CHANGELOG ADDED
@@ -0,0 +1,16 @@
1
+ == 0.2.3 (03/06/11)
2
+
3
+ * all tests pass
4
+ * readme simplified
5
+ * count now returns 0 for empty tables
6
+ * truncate table, or delete all rows (sikachu)
7
+ * fix up the single update row method (sikachu)
8
+ * if value is nil, insert empty string (wynst)
9
+ * fixes to exception handling and tests (troy)
10
+
11
+ == 0.2.2
12
+
13
+ * 1.9.2 compatibility through gdata_19 gem
14
+ * examples updated for 1.9.2
15
+ * datetime columns now include time
16
+
data/README.md ADDED
@@ -0,0 +1,122 @@
1
+ fusion-tables
2
+ ==============
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/).
5
+
6
+ Demo and examples
7
+ ------------------
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/)
12
+
13
+ Installation
14
+ -------------
15
+
16
+ ``` bash
17
+ gem install fusion_tables
18
+ ```
19
+
20
+ **Gem Dependencies**
21
+
22
+ * gdata_19 >= 1.1.2
23
+
24
+ **Rubies**
25
+
26
+ * 1.8.7
27
+ * 1.9.2
28
+
29
+ Usage
30
+ ------
31
+ ``` ruby
32
+ require 'fusion_tables'
33
+
34
+ # Connect to service
35
+ @ft = GData::Client::FusionTables.new
36
+ @ft.clientlogin(username, password)
37
+
38
+ # Browse existing tables
39
+ @ft.show_tables
40
+ # => [table_1, table_2]
41
+
42
+ # Getting table id suitable for using with google maps (see more below)
43
+ table_1.id #=> 42342 (the table's google id)
44
+
45
+ # Count data
46
+ table_1.count #=> 1
47
+
48
+ # Select data
49
+ table_1.select
50
+ #=> data
51
+
52
+ # Select data with conditions
53
+ table_1.select "name", "WHERE x=n"
54
+ #=> data
55
+
56
+ # Select ROWIDs
57
+ row_ids = table_1.select "ROWID"
58
+
59
+ # Drop tables
60
+ @ft.drop table_1.id # table id
61
+ @ft.drop [table_1.id, table_2.id] # arrays of table ids
62
+ @ft.drop /yacht/ # regex on table name
63
+
64
+ # Creating a table
65
+ cols = [{:name => "friend name", :type => 'string' },
66
+ {:name => "age", :type => 'number' },
67
+ {:name => "meeting time", :type => 'datetime' },
68
+ {:name => "where", :type => 'location' }]
69
+
70
+ new_table = @ft.create_table "My upcoming meetings", cols
71
+
72
+ # Inserting rows (auto chunks every 500)
73
+ data = [{"friend name" => "Eric Wimp",
74
+ "age" => 25,
75
+ "meeting time" => Time.utc(2010,"aug",10,20,15,1),
76
+ "where" => "29 Acacia Road, Nuttytown"}]
77
+ new_table.insert data
78
+
79
+ # Delete row
80
+ new_table.delete row_id
81
+ ```
82
+
83
+ Currently only single row UPDATE query is implemented.
84
+
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
92
+ ```
93
+
94
+ Known Issues
95
+ -------------
96
+
97
+ * The Google gdata_19 gem conflicts with the GData2 gem. Only current fix is to uninstall GData2.
98
+ * You have to make a table public before you can display it on a map. This can only be done via FT web interface.
99
+
100
+ Note on Patches/Pull Requests
101
+ ------------------------------
102
+
103
+ * Fork the project.
104
+ * Make your feature addition or bug fix.
105
+ * Add tests for it. This is important so I don't break it in a
106
+ future version unintentionally.
107
+ * Commit, do not mess with rakefile, version, or history.
108
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
109
+ * Send me a pull request. Bonus points for topic branches.
110
+
111
+
112
+
113
+ Contributors
114
+ -------------
115
+
116
+ Largely based on Tom Verbeure's [work for MTBGuru](http://code.google.com/p/mtbguru-fusiontables/)
117
+
118
+ * tokumine
119
+ * sikachu
120
+ * troy
121
+ * wynst
122
+
data/Rakefile CHANGED
@@ -12,6 +12,7 @@ begin
12
12
  gem.authors = ["Simon Tokumine", "Tom Verbeure"]
13
13
  gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
14
  gem.add_dependency "gdata_19", ">= 1.1.2"
15
+ gem.files.exclude 'pkg'
15
16
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
17
  end
17
18
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 0.2.3
@@ -0,0 +1,159 @@
1
+ # This library creates a FT and posts data from the Boris Bikes API to it every minute
2
+ #
3
+ # Add photos to infowindow
4
+ # Add fusion table graphs to the inside of the infowindows too
5
+
6
+
7
+ require 'net/http'
8
+ require 'uri'
9
+ require 'rubygems'
10
+ require 'geo_ruby'
11
+ require 'fusion_tables'
12
+ require 'time'
13
+ require 'json'
14
+ require 'yaml'
15
+ require 'ap'
16
+ include GeoRuby
17
+ include SimpleFeatures
18
+
19
+ class Object
20
+ def try(method, *args, &block)
21
+ send(method, *args, &block)
22
+ end
23
+ end
24
+
25
+ def color max, number_to_color, min=0, opacity=80
26
+ color = ["FFFFB2", "FFFFB2", "FEB24C", "FD8D3C", "F03B20", "BD0026"]
27
+ #color = %w(FEE0D2 FCBBA1 FC9272 FB6A4A EF3B2C CB181D A50F15 67000D)
28
+ color.reverse!
29
+ #color = ["FFFFCC", "D9F0A3", "ADDD8E", "78C679", "31A354", "31A354"] #<- greens
30
+ chunk = (max-min)/color.size
31
+ index = (number_to_color/chunk).floor
32
+ "#{color[index]}#{opacity}"
33
+ end
34
+
35
+ def to_google(x,y)
36
+ a = `echo "#{x} #{y}" | cs2cs + +init=epsg:4326 +to +init=epsg:3785 -f "%.12f"`
37
+ a = a.split(" ")
38
+ {:x => a[0], :y => a[1]}
39
+ end
40
+
41
+ def from_google(x,y)
42
+ a = `echo "#{x} #{y}" | cs2cs + +init=epsg:3785 +to +init=epsg:4326 -f "%.12f"`
43
+ a = a.split(" ")
44
+ {:x => a[0], :y => a[1]}
45
+ end
46
+
47
+
48
+ def buffer(center_x, center_y, radius, quality = 4, precision = 12)
49
+ points = []
50
+ radians = Math::PI / 180
51
+
52
+ coords = to_google(center_x, center_y)
53
+ center_x = coords[:x].to_f
54
+ center_y = coords[:y].to_f
55
+
56
+ 0.step(360, quality) do |i|
57
+ x = center_x + (radius * Math.cos(i * radians))
58
+ y = center_y + (radius * Math.sin(i * radians))
59
+ coords = from_google(x,y)
60
+ points << Point.from_x_y(round(coords[:x].to_f, precision), round(coords[:y].to_f, precision))
61
+ end
62
+ points
63
+ end
64
+
65
+
66
+ def round number, precision = 12
67
+ (number * 10**precision).round.to_f / 10**precision
68
+ end
69
+
70
+ # Configure settings
71
+ config = YAML::load_file(File.join(File.dirname(__FILE__), 'credentials.yml'))
72
+ DEFAULT_SRID = 4328
73
+
74
+
75
+ # Configure fusion tables
76
+ ft = GData::Client::FusionTables.new
77
+ ft.clientlogin(config["google_username"], config["google_password"])
78
+ table_name = "Boris Bikes"
79
+ cols = [
80
+ {:name => 'name', :type => 'string'},
81
+ {:name => 'created_at', :type => 'datetime'},
82
+ {:name => 'updated_at', :type => 'datetime'},
83
+ {:name => 'boris_id', :type => 'number'},
84
+ {:name => 'temporary', :type => 'number'},
85
+ {:name => 'installed', :type => 'number'},
86
+ {:name => 'locked', :type => 'number'},
87
+ {:name => 'nb_empty_docs',:type => 'number'},
88
+ {:name => 'nb_bikes', :type => 'number'},
89
+ {:name => 'nb_docs', :type => 'number'},
90
+ {:name => 'image', :type => 'string'},
91
+ {:name => 'geom', :type => 'location'},
92
+ {:name => 'geom_fill', :type => 'string'},
93
+ {:name => 'geom_border', :type => 'string'},
94
+ ]
95
+
96
+ # Create FT if it doesn't exist
97
+ tables = ft.show_tables
98
+ table = tables.select{|t| t.name == table_name}.first
99
+ table = ft.create_table(table_name, cols) if !table
100
+
101
+ while true do
102
+ bikes = JSON.parse(Net::HTTP.get(URI.parse('http://borisapi.heroku.com/stations.json')))
103
+
104
+ # get largest bike rack to calibrate buffer
105
+ max = 0
106
+ bikes.each do |b|
107
+ slots = b["nb_empty_docks"] + b["nb_bikes"]
108
+ max = slots if slots > max
109
+ end
110
+
111
+ # loop through data constructing fusion table date
112
+ data = []
113
+ max_radius = 150.0 #in meters
114
+ buffer_chunk = max_radius / max
115
+
116
+ bikes.each do |b|
117
+ if b["lat"].to_f > 50 #ignore non geographic ones
118
+ docs = (b["nb_bikes"] + b["nb_empty_docks"])
119
+ geom = Polygon.from_points [buffer(b["long"].to_f, b["lat"].to_f, docs*buffer_chunk)]
120
+ #geom = Point.from_x_y b["long"].to_f, b["lat"].to_f
121
+
122
+ data << {
123
+ "name" => b["name"],
124
+ "created_at" => Time::parse(b["created_at"]),
125
+ "updated_at" => Time::parse(b["updated_at"]),
126
+ "boris_id" => b["id"],
127
+ "temporary" => (b["temporary"] ? 1 : 0),
128
+ "installed" => (b["installed"] ? 1 : 0),
129
+ "locked" => (b["locked"] ? 1 : 0),
130
+ "nb_empty_docs" => b["nb_empty_docks"],
131
+ "nb_bikes" => b["nb_bikes"],
132
+ "nb_docs" => docs,
133
+ "image" => "",
134
+ "geom" => geom.as_kml,
135
+ "geom_fill" => color(max,b["nb_bikes"]),
136
+ "geom_border" => color(max,b["nb_bikes"],0,"FF"),
137
+ }
138
+ puts "packing data for #{b["name"]}"
139
+ end
140
+ end
141
+
142
+ # get current number of rows ready to delete
143
+ row_ids = table.select "ROWID"
144
+
145
+ # put new data up
146
+ puts "sending bikes to fusion tables..."
147
+ table.insert data
148
+
149
+ # remove old data
150
+ puts "deleting old rows"
151
+ row_ids.each do |id|
152
+ table.delete id[:rowid]
153
+ end
154
+
155
+ # Be nice and wait
156
+ puts "...done! sleeping..."
157
+ sleep 500
158
+ end
159
+
@@ -49,7 +49,7 @@ places = {
49
49
  # Configure fusion tables
50
50
  ft = GData::Client::FusionTables.new
51
51
  ft.clientlogin(config["google_username"], config["google_password"])
52
- table_name = "twitter_fusion_test"
52
+ table_name = "TwitterFusion"
53
53
  cols = [
54
54
  {:name => 'screen_name', :type => 'string'},
55
55
  {:name => 'avatar', :type => 'string'},
@@ -5,26 +5,28 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{fusion_tables}
8
- s.version = "0.2.2"
8
+ s.version = "0.2.3"
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{2010-09-02}
12
+ s.date = %q{2011-06-03}
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.textile",
17
+ "README.md",
18
18
  "TODO"
19
19
  ]
20
20
  s.files = [
21
21
  ".document",
22
22
  ".gitignore",
23
+ "CHANGELOG",
23
24
  "LICENSE",
24
- "README.textile",
25
+ "README.md",
25
26
  "Rakefile",
26
27
  "TODO",
27
28
  "VERSION",
29
+ "examples/boris_bikes.rb",
28
30
  "examples/compare_tweets.rb",
29
31
  "examples/credentials.example.yml",
30
32
  "fusion_tables.gemspec",
@@ -33,12 +35,6 @@ Gem::Specification.new do |s|
33
35
  "lib/fusion_tables/data/data.rb",
34
36
  "lib/fusion_tables/data/table.rb",
35
37
  "lib/fusion_tables/ext/fusion_tables.rb",
36
- "pkg/fusion_tables-0.1.0.gem",
37
- "pkg/fusion_tables-0.1.1.gem",
38
- "pkg/fusion_tables-0.1.2.gem",
39
- "pkg/fusion_tables-0.2.0.gem",
40
- "pkg/fusion_tables-0.2.1.gem",
41
- "pkg/fusion_tables-0.2.2.gem",
42
38
  "test/README",
43
39
  "test/helper.rb",
44
40
  "test/test_client.rb",
@@ -49,18 +45,18 @@ Gem::Specification.new do |s|
49
45
  s.homepage = %q{http://github.com/tokumine/fusion-tables}
50
46
  s.rdoc_options = ["--charset=UTF-8"]
51
47
  s.require_paths = ["lib"]
52
- s.rubygems_version = %q{1.3.7}
48
+ s.rubygems_version = %q{1.4.1}
53
49
  s.summary = %q{Google Fusion Tables API wrapper}
54
50
  s.test_files = [
55
51
  "test/helper.rb",
56
52
  "test/test_client.rb",
57
53
  "test/test_ext.rb",
58
54
  "test/test_table.rb",
55
+ "examples/boris_bikes.rb",
59
56
  "examples/compare_tweets.rb"
60
57
  ]
61
58
 
62
59
  if s.respond_to? :specification_version then
63
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
64
60
  s.specification_version = 3
65
61
 
66
62
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
@@ -52,8 +52,10 @@ module GData
52
52
 
53
53
  # Returns a count of rows. SQL conditions optional
54
54
  #
55
+ # Note: handles odd FT response: when table has 0 rows, returns empty array.
55
56
  def count conditions=nil
56
- select("count()", conditions).first.values.first.to_i
57
+ result = select("count()", conditions)
58
+ result.empty? ? 0 : result.first[:"count()"].to_i
57
59
  end
58
60
 
59
61
 
@@ -66,7 +68,8 @@ module GData
66
68
  # Fields are escaped and formatted for FT based on type
67
69
  #
68
70
  def insert data
69
-
71
+ data = [data] unless data.respond_to?(:to_ary)
72
+
70
73
  # encode values to insert
71
74
  data = encode data
72
75
 
@@ -85,26 +88,24 @@ module GData
85
88
  end
86
89
  end
87
90
 
88
- # Runs update on rows and return data obj
89
- # No bulk update, so may aswell drop table and start again
90
- #
91
- # TODO: FIXME
92
- #
93
- #def update row_id, data
94
- # data = encode([data]).first
95
- # data = data.to_a.map{|x| x.join("=")}.join(", ")
96
- #
97
- # sql = "UPDATE #{@id} SET #{data} WHERE ROWID = #{row_id}"
98
- # GData::Client::FusionTables::Data.parse(@client.sql_post(sql)).body
99
- #end
91
+ # Runs update on row specified and return data obj
92
+ def update row_id, data
93
+ data = encode([data]).first
94
+ 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
97
+ end
100
98
 
101
99
  # delete row
102
- # no bulk delete so may aswell drop table and start again
103
100
  def delete row_id
104
101
  sql = "DELETE FROM #{@id} WHERE rowid='#{row_id}'"
105
102
  GData::Client::FusionTables::Data.parse(@client.sql_post(sql)).body
106
103
  end
107
104
 
105
+ # delete all rows
106
+ def truncate!
107
+ GData::Client::FusionTables::Data.parse(@client.sql_post("DELETE FROM #{@id}")).body
108
+ end
108
109
 
109
110
  def get_headers
110
111
  @headers ||= describe
@@ -114,10 +115,15 @@ module GData
114
115
  data.inject([]) do |ar,h|
115
116
  ret = {}
116
117
  h.each do |key, value|
117
- ret["'#{key.to_s}'"] = case get_datatype(key)
118
- when "number" then "#{value}"
119
- when "datetime" then "'#{value.strftime("%m-%d-%Y %H:%M:%S")}'"
120
- else "'#{value.gsub(/\\/, '\&\&').gsub(/'/, "''")}'"
118
+ if value.nil?
119
+ #empty string for nils
120
+ ret["'#{key.to_s}'"] = "''"
121
+ else
122
+ ret["'#{key.to_s}'"] = case get_datatype(key)
123
+ when "number" then "#{value}"
124
+ when "datetime" then "'#{value.strftime("%m-%d-%Y %H:%M:%S")}'"
125
+ else "'#{value.gsub(/\\/, '\&\&').gsub(/'/, "''")}'"
126
+ end
121
127
  end
122
128
  end
123
129
  ar << ret
@@ -134,9 +140,9 @@ module GData
134
140
  @headers.each do |h|
135
141
  return h[:type] if h[:name] == column_name.to_s
136
142
  end
137
- raise ArgumentError "The column doesn't exist"
143
+ raise ArgumentError, "The column doesn't exist"
138
144
  end
139
145
  end
140
146
  end
141
147
  end
142
- end
148
+ end
data/test/test_client.rb CHANGED
@@ -10,12 +10,12 @@ class TestClient < Test::Unit::TestCase
10
10
  end
11
11
 
12
12
  should "be properly setup" do
13
- assert_equal @ft.clientlogin_service, "fusiontables"
14
- assert_equal @ft.headers["Content-Type"], "application/x-www-form-urlencoded"
13
+ assert_equal "fusiontables", @ft.clientlogin_service
14
+ assert_equal "application/x-www-form-urlencoded", @ft.headers["Content-Type"]
15
15
  end
16
16
 
17
17
  should "be able to authenticate with the google services" do
18
- assert_equal @ft.auth_handler.service, "fusiontables"
18
+ assert_equal "fusiontables", @ft.auth_handler.service
19
19
  assert @ft.auth_handler.token
20
20
  end
21
21
  end
data/test/test_ext.rb CHANGED
@@ -18,40 +18,40 @@ class TestExt < Test::Unit::TestCase
18
18
 
19
19
  should "let you create a table if you get everything right" do
20
20
  table = @ft.create_table "test_table", [{:name => "test_col", :type => "string" }]
21
- assert_equal table.class, GData::Client::FusionTables::Table
21
+ assert_equal GData::Client::FusionTables::Table, table.class
22
22
  @ft.drop(table.id)
23
23
  end
24
-
24
+
25
25
  should "correct your table name to a certain degree on create" do
26
26
  table = @ft.create_table "test table", [{:name => "test col", :type => "string" }]
27
- assert_equal table.name, "test_table"
27
+ assert_equal "test_table", table.name
28
28
  @ft.drop(table.id)
29
29
  end
30
-
30
+
31
31
  should "return you a list of your fusion tables" do
32
32
  resp = @ft.show_tables
33
- assert_equal resp.first.class, GData::Client::FusionTables::Table if resp.first
33
+ assert_equal GData::Client::FusionTables::Table, resp.first.class if resp.first
34
34
  end
35
35
 
36
36
  should "be possible to delete a table with an id" do
37
37
  table = @ft.create_table "test_table", [{:name => "test col", :type => "string" }]
38
- assert_equal @ft.drop(table.id), 1
38
+ assert_equal 1, @ft.drop(table.id)
39
39
  end
40
-
40
+
41
41
  should "be possible to delete tables with an array of ids" do
42
42
  table1 = @ft.create_table "test_table", [{:name => "test col", :type => "string" }]
43
43
  table2 = @ft.create_table "test_table", [{:name => "test col", :type => "string" }]
44
- assert_equal @ft.drop([table1.id, table2.id]), 2
44
+ assert_equal 2, @ft.drop([table1.id, table2.id])
45
45
  end
46
-
46
+
47
47
  should "be possible to delete multiple tables with a regex" do
48
48
  table1 = @ft.create_table "test_table", [{:name => "test col", :type => "string" }]
49
49
  table2 = @ft.create_table "test_table", [{:name => "test col", :type => "string" }]
50
- assert_equal @ft.drop(/^test_/), 2
50
+ assert_equal 2, @ft.drop(/^test_/)
51
51
  end
52
-
52
+
53
53
  should "return zero if passed a silly id" do
54
- assert_equal @ft.drop(235243875629384756), 0
54
+ assert_equal 0, @ft.drop(235243875629384756)
55
55
  end
56
56
  end
57
57
 
data/test/test_table.rb CHANGED
@@ -18,12 +18,11 @@ class TestTable < Test::Unit::TestCase
18
18
  :phone => 12,
19
19
  :dob => Time.utc(2010,"aug",10,20,15,1),
20
20
  :house => "POINT(1,1)"}]
21
-
22
21
  row = data.first
23
- assert_equal row[:firstname], "'\\\\bob''s pizza'"
24
- assert_equal row[:phone], "#{12}"
25
- assert_equal row[:dob], "'08-10-2010'"
26
- assert_equal row[:house], "'POINT(1,1)'"
22
+ assert_equal "'\\\\bob''s pizza'", row["'firstname'"]
23
+ assert_equal "#{12}", row["'phone'"]
24
+ assert_equal "'08-10-2010 20:15:01'", row["'dob'"]
25
+ assert_equal "'POINT(1,1)'", row["'house'"]
27
26
  end
28
27
 
29
28
  should "be able to insert 1 row of data" do
@@ -33,7 +32,7 @@ class TestTable < Test::Unit::TestCase
33
32
  :dob => Time.utc(2010,"aug",10,20,15,1),
34
33
  :house => '<Point><coordinates>-74.006393,40.714172,0</coordinates></Point>'}
35
34
  }
36
-
35
+
37
36
  @table.insert data
38
37
  end
39
38
 
@@ -47,8 +46,8 @@ class TestTable < Test::Unit::TestCase
47
46
 
48
47
  @table.insert data
49
48
  end
50
-
51
-
49
+
50
+
52
51
  should "be able to count the number of rows" do
53
52
  data = 2.times.inject([]) { |a,i|
54
53
  a << {:firstname => "Person-#{i}",
@@ -56,9 +55,9 @@ class TestTable < Test::Unit::TestCase
56
55
  :dob => Time.utc(2010,"aug",10,20,15,1),
57
56
  :house => "<Point><coordinates>#{180-rand(360)},#{90-rand(180)},0</coordinates></Point>"}
58
57
  }
59
-
58
+
60
59
  @table.insert data
61
- assert_equal @table.count, 2
60
+ assert_equal 2, @table.count
62
61
  end
63
62
 
64
63
  should "be able to select the rows" do
@@ -68,9 +67,25 @@ class TestTable < Test::Unit::TestCase
68
67
  :dob => Time.utc(2010,"aug",10,20,15,1),
69
68
  :house => "<Point><coordinates>1,1,0</coordinates></Point>"}
70
69
  }
71
-
70
+
72
71
  @table.insert data
73
- assert_equal @table.select, [{:firstname=>"Person-0", :phone=>"12", :dob=>"08-10-2010", :house=>"<Point><coordinates>1,1,0</coordinates></Point>"}, {:firstname=>"Person-1", :phone=>"12", :dob=>"08-10-2010", :house=>"<Point><coordinates>1,1,0</coordinates></Point>"}]
72
+ assert_equal [{:firstname=>"Person-0", :phone=>"12", :dob=>"08-10-2010 20:15:01", :house=>"<Point><coordinates>1,1,0</coordinates></Point>"}, {:firstname=>"Person-1", :phone=>"12", :dob=>"08-10-2010 20:15:01", :house=>"<Point><coordinates>1,1,0</coordinates></Point>"}], @table.select
74
73
  end
74
+
75
+ should "be able to truncate all rows and start again" do
76
+ data = 2.times.inject([]) { |a,i|
77
+ a << {:firstname => "Person-#{i}",
78
+ :phone => 12,
79
+ :dob => Time.utc(2010,"aug",10,20,15,1),
80
+ :house => "<Point><coordinates>#{180-rand(360)},#{90-rand(180)},0</coordinates></Point>"}
81
+ }
82
+
83
+ @table.insert data
84
+ assert_equal 2, @table.count
85
+ @table.truncate!
86
+ assert_equal 0, @table.count
87
+ @table.insert data
88
+ assert_equal 2, @table.count
89
+ end
75
90
  end
76
91
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fusion_tables
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 17
5
+ prerelease:
5
6
  segments:
6
7
  - 0
7
8
  - 2
8
- - 2
9
- version: 0.2.2
9
+ - 3
10
+ version: 0.2.3
10
11
  platform: ruby
11
12
  authors:
12
13
  - Simon Tokumine
@@ -15,7 +16,7 @@ autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2010-09-02 00:00:00 +01:00
19
+ date: 2011-06-03 00:00:00 +01:00
19
20
  default_executable:
20
21
  dependencies:
21
22
  - !ruby/object:Gem::Dependency
@@ -26,6 +27,7 @@ dependencies:
26
27
  requirements:
27
28
  - - ">="
28
29
  - !ruby/object:Gem::Version
30
+ hash: 3
29
31
  segments:
30
32
  - 0
31
33
  version: "0"
@@ -39,6 +41,7 @@ dependencies:
39
41
  requirements:
40
42
  - - ">="
41
43
  - !ruby/object:Gem::Version
44
+ hash: 23
42
45
  segments:
43
46
  - 1
44
47
  - 1
@@ -54,16 +57,18 @@ extensions: []
54
57
 
55
58
  extra_rdoc_files:
56
59
  - LICENSE
57
- - README.textile
60
+ - README.md
58
61
  - TODO
59
62
  files:
60
63
  - .document
61
64
  - .gitignore
65
+ - CHANGELOG
62
66
  - LICENSE
63
- - README.textile
67
+ - README.md
64
68
  - Rakefile
65
69
  - TODO
66
70
  - VERSION
71
+ - examples/boris_bikes.rb
67
72
  - examples/compare_tweets.rb
68
73
  - examples/credentials.example.yml
69
74
  - fusion_tables.gemspec
@@ -72,12 +77,6 @@ files:
72
77
  - lib/fusion_tables/data/data.rb
73
78
  - lib/fusion_tables/data/table.rb
74
79
  - lib/fusion_tables/ext/fusion_tables.rb
75
- - pkg/fusion_tables-0.1.0.gem
76
- - pkg/fusion_tables-0.1.1.gem
77
- - pkg/fusion_tables-0.1.2.gem
78
- - pkg/fusion_tables-0.2.0.gem
79
- - pkg/fusion_tables-0.2.1.gem
80
- - pkg/fusion_tables-0.2.2.gem
81
80
  - test/README
82
81
  - test/helper.rb
83
82
  - test/test_client.rb
@@ -98,6 +97,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
98
97
  requirements:
99
98
  - - ">="
100
99
  - !ruby/object:Gem::Version
100
+ hash: 3
101
101
  segments:
102
102
  - 0
103
103
  version: "0"
@@ -106,13 +106,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - ">="
108
108
  - !ruby/object:Gem::Version
109
+ hash: 3
109
110
  segments:
110
111
  - 0
111
112
  version: "0"
112
113
  requirements: []
113
114
 
114
115
  rubyforge_project:
115
- rubygems_version: 1.3.7
116
+ rubygems_version: 1.4.1
116
117
  signing_key:
117
118
  specification_version: 3
118
119
  summary: Google Fusion Tables API wrapper
@@ -121,4 +122,5 @@ test_files:
121
122
  - test/test_client.rb
122
123
  - test/test_ext.rb
123
124
  - test/test_table.rb
125
+ - examples/boris_bikes.rb
124
126
  - examples/compare_tweets.rb
data/README.textile DELETED
@@ -1,144 +0,0 @@
1
- h1. fusion-tables
2
-
3
- This gem lets you easily interact with Google Fusion Tables from your Ruby application. Here are some "example maps and charts":http://www.tokumine.com/2010/08/10/fusion-tables-gem/.
4
-
5
- h2. Gem Dependencies
6
-
7
- * gdata_19 >= 1.1.2
8
-
9
- h2. Installation
10
-
11
- bc. gem install fusion_tables
12
-
13
- h2. Rubies
14
-
15
- Tested on:
16
-
17
- * 1.8.7
18
- * 1.9.2-p0
19
-
20
- h2. To Use
21
-
22
- bc. require 'fusion_tables'
23
-
24
- or in Rails 2.3.x
25
-
26
- bc. config.gem 'fusion_tables'
27
-
28
- h2. API examples
29
-
30
- Please explore the "worked twitter example":http://github.com/tokumine/fusion-tables/blob/master/examples/compare_tweets.rb and the "tests":http://github.com/tokumine/fusion-tables/tree/master/test/. Here is a brief rundown:
31
-
32
- <pre><code># Connect to service
33
- @ft = GData::Client::FusionTables.new
34
- @ft.clientlogin(username, password)
35
-
36
- # Browse existing tables
37
- @ft.show_tables
38
- # => [table_1, table_2]
39
-
40
- # Getting table id suitable for using with google maps (see more below)
41
- table_1.id #=> 42342 (the table's google id)
42
-
43
- # Count data
44
- table_1.count #=> 1
45
-
46
- # Select data
47
- table_1.select
48
- #=> data
49
-
50
- # Select data with conditions
51
- table_1.select "name", "WHERE x=n"
52
- #=> data
53
-
54
- # Select ROWIDs
55
- row_ids = table_1.select "ROWID"
56
-
57
- # Drop tables
58
- @ft.drop table_1.id # table id
59
- @ft.drop [table_1.id, table_2.id] # arrays of table ids
60
- @ft.drop /yacht/ # regex on table name
61
-
62
- # Creating a table
63
- cols = [{:name => "friend name", :type => 'string' },
64
- {:name => "age", :type => 'number' },
65
- {:name => "meeting time", :type => 'datetime' },
66
- {:name => "where", :type => 'location' }]
67
-
68
- new_table = @ft.create_table "My upcoming meetings", cols
69
-
70
- # Inserting rows (auto chunks every 500)
71
- data = [{"friend name" => "Eric Wimp",
72
- "age" => 25,
73
- "meeting time" => Time.utc(2010,"aug",10,20,15,1),
74
- "where" => "29 Acacia Road, Nuttytown"}]
75
- new_table.insert data
76
-
77
- # Delete row
78
- new_table.delete row_id
79
- </code></pre>
80
-
81
- h2. Fusion Tables secret Geospatial Sauce
82
-
83
- *"Geolocated Tweets example":http://tables.googlelabs.com/DataSource?snapid=73106*
84
-
85
- Fusion Tables is a labs product from Google. You can "read more here":http://tables.googlelabs.com/, but the key thing is that it gives you *access to the google tile mill for fast generation of google map layers across large datasets*
86
-
87
- Fusion Tables supports the following geometry types:
88
-
89
- * lat/long
90
- * addresses (automatically geocodes them for you)
91
- * KML (point, polyline, polygon, multipolygon)
92
-
93
- h2. Integrate with google maps v3
94
-
95
- Adding a fusion tables datalayer with many points/polygons to your v3 map is as simple as:
96
-
97
- bc. layer = new google.maps.FusionTablesLayer(139529);
98
-
99
- That's it
100
-
101
- You can also refine the tiles by SQL, and can even do so dynamically:
102
-
103
- <pre><code>
104
- layer = new google.maps.FusionTablesLayer(198945, {
105
- query: "SELECT address FROM 198945 WHERE ridership > 5000"}
106
- );
107
- </code></pre>
108
-
109
- Finally, fusion tables also lets you make Heatmaps
110
-
111
- <pre><code>
112
- layer = new google.maps.FusionTablesLayer(136705, {
113
- heatmap: true
114
- });
115
- </code></pre>
116
-
117
- You can also export your data (filtered and geocoded) to KML. As an example, here are "all the Gasoline filling stations in the UK":http://tables.googlelabs.com/exporttable?query=select+col0%2Ccol1%2Ccol2%2Ccol3%2Ccol4%2Ccol5%2Ccol6%2Ccol12%2Ccol13%2Ccol14%2Ccol15%2Ccol16%2Ccol17%2Ccol18%2Ccol19%2Ccol20%2Ccol21+from+214045+&o=kmllink&g=col0
118
-
119
- read "more here":http://code.google.com/apis/maps/documentation/javascript/overlays.html#FusionTables
120
-
121
- h2. A few words of warning...
122
-
123
- # The API is still very young and *will probably change*
124
- # Currently you have to make a table public before you can display it on a map, unfortunately, this can only be done on the web interface. A suggested workaround is to put all your data in 1 big public table, and then query for the data you want to display based off a key/flag column
125
-
126
- h2. Note on Patches/Pull Requests
127
-
128
- * Fork the project.
129
- * Make your feature addition or bug fix.
130
- * Add tests for it. This is important so I don't break it in a
131
- future version unintentionally.
132
- * Commit, do not mess with rakefile, version, or history.
133
- (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
134
- * Send me a pull request. Bonus points for topic branches.
135
-
136
- h2. Copyright
137
-
138
- Largely based on Tom Verbeure's work for MTBGuru: http://code.google.com/p/mtbguru-fusiontables/
139
-
140
- Copyright (c) 2010 Tom Verbeure, Simon Tokumine. See LICENSE for details.
141
-
142
-
143
-
144
-
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file