cartodb-rb-client 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,4 +2,5 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
- bin/
5
+ bin/
6
+ spec/support/cartodb_config.yml
data/Gemfile CHANGED
@@ -5,8 +5,8 @@ gemspec
5
5
 
6
6
  group :development do
7
7
  gem "rspec", "~> 2.3.0"
8
- gem "bundler", "~> 1.0.0"
9
- gem "rcov", ">= 0"
8
+ gem "spork", "~> 0.9.0"
9
+ gem "bundler", "> 1.0.0"
10
10
  gem 'ruby-debug', :platforms => :mri_18
11
11
  gem 'ruby-debug19', :require => 'ruby-debug', :platforms => :mri_19
12
12
  end
data/README.markdown CHANGED
@@ -38,17 +38,13 @@ Setup
38
38
  username: 'YOUR_CARTODB_USERNAME'
39
39
  password: 'YOUR_CARTODB_PASSWORD'
40
40
 
41
- 3. Setup your cartoDB connection object. To do so, load the YAML file and assign it to a CartoDB::Config object:
42
-
43
- CartoDB::Settings = YAML.load_file(Rails.root.join('config/cartodb_config.yml'))
44
- CartoDB::Connection = CartoDB::Client::Connection.new
41
+ 3. Setup your cartoDB connection object:
45
42
 
43
+ CartoDB::Init.start YAML.load_file(Rails.root.join('config/cartodb_config.yml'))
44
+
46
45
  And that's it. Now you should be able to run querys against the cartoDB servers using the CartoDB::Connection object.
47
46
 
48
- Rails apps
49
- ----------
50
-
51
- If you're developing a Rails app, you just need to add the cartodb\_config.yml file to your rails app config directory. And that's it. You can access cartoDB anywhere in your app's code using the CartoDB::Connection class.
47
+ Note: You have to use strings instead of symbols for the configuration hash keys.
52
48
 
53
49
  Using the cartoDB API
54
50
  -----------
@@ -63,11 +59,11 @@ Arguments:
63
59
 
64
60
  - **table\_name**: table's name.
65
61
 
66
- - **schema**: list of fields the table will contain.
62
+ - **schema_or_file**: this parameter can be a list of fields the table will contain, or a File class containing the data the table will contain. It supports all file types supported by cartoDB.
67
63
 
68
64
  - **the\_geom\_type**: Type of geometry the\_geom field will have. Currently we only support 'POINT', but we'll support more types soon.
69
65
 
70
- Example:
66
+ Example 1:
71
67
 
72
68
  CartoDB::Connection.create_table 'table #1', [{:name => 'field1', :type => 'text'}], 'POINT'
73
69
 
@@ -81,6 +77,40 @@ Results:
81
77
  ["updated_at", "date"],
82
78
  ["created_at", "date"]]}
83
79
 
80
+ Example 2:
81
+
82
+ CartoDB::Connection.create_table 'whs_sites', File.open("#{File.dirname(__FILE__)}/support/whs_features.csv", 'r')
83
+
84
+ Results:
85
+
86
+ {:id=>242,
87
+ :name=>"_20120314_21932_1fx2580whs_features",
88
+ :schema=>
89
+ [["cartodb_id", "number"],
90
+ ["the_geom", "geometry", "geometry", "point"],
91
+ ["comments", "string"],
92
+ ["country", "string"],
93
+ ["criteria", "string"],
94
+ ["date_of_inscription", "string"],
95
+ ["description", "string"],
96
+ ["edited_region", "string"],
97
+ ["endangered_reason", "string"],
98
+ ["endangered_year", "string"],
99
+ ["external_links", "string"],
100
+ ["iso_code", "string"],
101
+ ["latitude", "string"],
102
+ ["longitude", "string"],
103
+ ["name", "string"],
104
+ ["region", "string"],
105
+ ["size", "string"],
106
+ ["title", "string"],
107
+ ["type", "string"],
108
+ ["whs_site_id", "string"],
109
+ ["whs_source_page", "string"],
110
+ ["wikipedia_link", "string"],
111
+ ["created_at", "date"],
112
+ ["updated_at", "date"]]}
113
+
84
114
  ####2. Add column.
85
115
 
86
116
  Adds a new column to an existing table.
@@ -178,7 +208,7 @@ Results:
178
208
  :name => "table_1",
179
209
  :privacy => "PRIVATE",
180
210
  :tags => "",
181
- :schema =>
211
+ :schema =>
182
212
  [["cartodb_id", "number"],
183
213
  ["myfield", "boolean"],
184
214
  ["updated_at", "date"],
@@ -22,10 +22,10 @@ Gem::Specification.new do |s|
22
22
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
23
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
24
  s.require_paths = ["lib"]
25
- s.add_dependency 'typhoeus', '0.2.4'
25
+ s.add_dependency 'typhoeus', '0.3.3'
26
26
  s.add_dependency 'oauth', '0.4.5'
27
- s.add_dependency 'mime-types', '1.16'
28
- s.add_dependency 'activesupport', '>= 3.0.0', '<= 3.1.0'
27
+ s.add_dependency 'mime-types', '>= 1.16'
28
+ s.add_dependency 'activesupport', '>= 3.0.0'
29
29
  s.add_dependency 'i18n', '>= 0.5.0', '<= 0.6.0'
30
30
  s.add_dependency 'rgeo', '0.3.2'
31
31
  s.add_dependency 'rgeo-geojson', '0.2.1'
@@ -4,11 +4,15 @@ module CartoDB
4
4
  module Client
5
5
  module Authorization
6
6
 
7
+ CRLF = "\r\n"
8
+
7
9
  def signed_request(request_uri, arguments)
8
10
  arguments[:disable_ssl_peer_verification] = true
9
11
 
10
12
  request = Typhoeus::Request.new(request_uri, arguments)
11
13
 
14
+ request = as_multipart(request, arguments[:params]) if arguments[:multipart] == true
15
+
12
16
  request.headers.merge!({"Authorization" => oauth_helper(request, request_uri).header})
13
17
 
14
18
  request
@@ -53,6 +57,30 @@ module CartoDB
53
57
  end
54
58
  private :oauth_helper
55
59
 
60
+ def as_multipart(request, params)
61
+
62
+ boundary = Time.now.to_i.to_s(16)
63
+ request.headers["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
64
+ body = ""
65
+ params.each do |key,value|
66
+ esc_key = CGI.escape(key.to_s)
67
+ body << "--#{boundary}#{CRLF}"
68
+ if value.respond_to?(:read)
69
+ body << "Content-Disposition: form-data; name=\"#{esc_key}\"; filename=\"#{File.basename(value.path)}\"#{CRLF}"
70
+ body << "Content-Type: application/octet-stream#{CRLF*2}"
71
+ body << value.read.force_encoding('utf-8')
72
+ else
73
+ body << "Content-Disposition: form-data; name=\"#{esc_key}\"#{CRLF*2}#{value}"
74
+ end
75
+ body << CRLF
76
+ end
77
+ body << "--#{boundary}--#{CRLF*2}"
78
+ request.body = body
79
+ request.params = {}
80
+ request
81
+ end
82
+ private :as_multipart
83
+
56
84
  end
57
85
  end
58
86
  end
@@ -14,14 +14,66 @@ module CartoDB
14
14
  end
15
15
 
16
16
  def create_table(table_name = nil, schema_or_file = nil, the_geom_type = 'Point')
17
- schema = schema_or_file if schema_or_file && schema_or_file.is_a?(Array)
18
- file = schema_or_file if schema_or_file && schema_or_file.is_a?(File)
19
17
 
20
18
  params = {:name => table_name}
21
- params[:file] = file if file
22
- params[:schema] = schema.map{|s| "#{s[:name]} #{s[:type]}"}.join(', ') if schema
19
+ params[:the_geom_type] = the_geom_type.downcase if the_geom_type.present?
23
20
 
24
- request = cartodb_request 'tables', :post, :params => params, :the_geom_type => the_geom_type do |response|
21
+ case schema_or_file
22
+
23
+ when String
24
+
25
+ params[:the_geom_type] = schema_or_file.downcase
26
+
27
+ request = cartodb_request 'tables', :post, :params => params do |response|
28
+ return Utils.parse_json(response)
29
+ end
30
+
31
+ when Array
32
+
33
+ schema = schema_or_file if schema_or_file && schema_or_file.is_a?(Array)
34
+ params[:schema] = schema.map{|s| "#{s[:name]} #{s[:type]}"}.join(', ') if schema
35
+
36
+ request = cartodb_request 'tables', :post, :params => params do |response|
37
+ return Utils.parse_json(response)
38
+ end
39
+
40
+ when File
41
+
42
+ file = schema_or_file if schema_or_file && schema_or_file.is_a?(File)
43
+
44
+ request = cartodb_request nil, :post, :url => '/upload', :params => {:file => file}, :multipart => true do |response|
45
+ upload_response = Utils.parse_json(response)
46
+
47
+ params = {:name => table_name}
48
+ params[:url] = generate_url upload_response[:file_uri]
49
+ params[:the_geom_type] = the_geom_type.downcase if the_geom_type.present?
50
+
51
+ request = cartodb_request 'tables', :post, :params => params do |response|
52
+ return Utils.parse_json(response)
53
+ end
54
+
55
+ end
56
+
57
+ else
58
+
59
+ request = cartodb_request 'tables', :post, :params => params do |response|
60
+ return Utils.parse_json(response)
61
+ end
62
+
63
+ end
64
+
65
+ execute_queue
66
+
67
+ request.handled_response
68
+
69
+ end
70
+
71
+ def rename_table(old_table_name, new_table_name)
72
+ request = cartodb_request "tables/#{old_table_name}",
73
+ :put,
74
+ :params => {
75
+ :name => new_table_name
76
+ } do |response|
25
77
  return Utils.parse_json(response)
26
78
  end
27
79
 
@@ -101,11 +153,8 @@ module CartoDB
101
153
  results = query(<<-SQL
102
154
  INSERT INTO #{table_name}
103
155
  (#{row.keys.join(',')})
104
- VALUES (#{row.values.join(',')});
105
-
106
- SELECT #{table_name}.cartodb_id as id, #{table_name}.*
107
- FROM #{table_name}
108
- WHERE cartodb_id = currval('public.#{table_name}_cartodb_id_seq');
156
+ VALUES (#{row.values.join(',')})
157
+ RETURNING cartodb_id as id, *;
109
158
  SQL
110
159
  )
111
160
 
@@ -119,10 +168,8 @@ module CartoDB
119
168
  UPDATE #{table_name}
120
169
  SET (#{row.keys.join(',')})
121
170
  = (#{row.values.join(',')})
122
- WHERE cartodb_id = #{row_id};
123
- SELECT #{table_name}.cartodb_id as id, #{table_name}.*
124
- FROM #{table_name}
125
- WHERE cartodb_id = currval('public.#{table_name}_cartodb_id_seq');
171
+ WHERE cartodb_id = #{row_id}
172
+ RETURNING cartodb_id as id, *;
126
173
  SQL
127
174
  )
128
175
 
@@ -178,6 +225,7 @@ module CartoDB
178
225
 
179
226
  uri = "/api/#{VERSION}/#{uri}"
180
227
  url = generate_url uri
228
+ url = generate_url(arguments[:url]) if arguments[:url]
181
229
 
182
230
  headers = {}
183
231
  headers['Accept'] = MIME::Types['application/json']
@@ -187,6 +235,7 @@ module CartoDB
187
235
  :method => method,
188
236
  :headers => headers,
189
237
  :params => params,
238
+ :multipart => arguments[:multipart],
190
239
  :cache_timeout => settings['cache_timeout'],
191
240
  :verbose => settings['debug']
192
241
  )
@@ -1,20 +1,26 @@
1
1
  module CartoDB
2
2
  module Helpers
3
3
  module SqlHelper
4
+ require 'time'
4
5
 
5
6
  def prepare_data(hash)
6
7
  hash.each do |key, value|
7
- hash[key] = format_value(value)
8
+ hash[key] = format_value(key, value)
8
9
  end
9
10
  hash
10
11
  end
11
12
 
12
- def format_value(value)
13
+ def format_value(key, value)
13
14
  case value
14
15
  when ::String
15
- "'#{value}'"
16
+ #value = value.gsub(/\\/, '\&\&').gsub(/'/, "''")
17
+ if key.match(/geo/)
18
+ "#{value}"
19
+ else
20
+ "'#{value.gsub(/\\/, '\&\&').gsub(/'/, "''")}'"
21
+ end
16
22
  when ::Date, ::DateTime, ::Time
17
- "'#{value}'"
23
+ "'#{value.to_time.utc}'"
18
24
  when RGeo::Feature::Geometry
19
25
  "'#{RGeo::WKRep::WKBGenerator.new(:type_format => :ewkb, :emit_ewkb_srid => true, :hex_format => true).generate(value)}'"
20
26
  when NilClass
@@ -34,6 +34,7 @@ module CartoDB
34
34
  self.send :define_method, :latitude do
35
35
  self.the_geom ? self.the_geom.y : nil
36
36
  end
37
+
37
38
  self.send :define_method, :longitude do
38
39
  self.the_geom ? self.the_geom.x : nil
39
40
  end
@@ -2,6 +2,12 @@ module CartoDB
2
2
  module Types
3
3
  class Metadata < Hash
4
4
 
5
+ RESERVED_WORDS = %w(
6
+ alias and BEGIN begin break case class def defined? do else elsif END end
7
+ ensure false for if in module next nil not or redo rescue retry return self
8
+ super then true undef unless until when while yield
9
+ )
10
+
5
11
  class << self
6
12
  def from_hash(hash = {})
7
13
  metadata = self.new
@@ -14,6 +20,8 @@ module CartoDB
14
20
  end
15
21
 
16
22
  def []=(key, value)
23
+ key = :"#{key}_" if RESERVED_WORDS.include?(key.to_s)
24
+
17
25
  if key.to_s.eql?('the_geom')
18
26
  value = _geometry_features(value)
19
27
  else
@@ -1,7 +1,7 @@
1
1
  module Cartodb
2
2
  module Rb
3
3
  module Client
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
6
6
  end
7
7
  end
data/spec/client_spec.rb CHANGED
@@ -20,11 +20,11 @@ describe 'CartoDB client' do
20
20
 
21
21
  it "should create a table forcing the schema and get its table definition" do
22
22
  table = CartoDB::Connection.create_table 'cartodb_spec', [
23
- {:name => 'field1', :type => 'text'},
24
- {:name => 'field2', :type => 'numeric'},
25
- {:name => 'field3', :type => 'date'},
26
- {:name => 'field4', :type => 'boolean'}
27
- ]
23
+ {:name => 'field1', :type => 'text'},
24
+ {:name => 'field2', :type => 'numeric'},
25
+ {:name => 'field3', :type => 'date'},
26
+ {:name => 'field4', :type => 'boolean'}
27
+ ]
28
28
 
29
29
  table.should_not be_nil
30
30
  table = CartoDB::Connection.table 'cartodb_spec'
@@ -38,43 +38,105 @@ describe 'CartoDB client' do
38
38
  table.schema.should include(["field4", "boolean"])
39
39
  end
40
40
 
41
- # it "should create a table from a csv file" do
42
- # table = CartoDB::Connection.create_table 'whs_sites', File.open("#{File.dirname(__FILE__)}/support/whs_features.csv", 'r')
43
- #
44
- # table.should_not be_nil
45
- # table[:id].should be > 0
46
- # table = CartoDB::Connection.table 'whs_sites'
47
- # table.schema.should have(23).items
48
- #
49
- # records = CartoDB::Connection.records 'whs_sites', :rows_per_page => 1000
50
- # records.should_not be_nil
51
- # records.rows.should have(911).whs_sites
52
- #
53
- # records.rows.first.cartodb_id.should be > 0
54
- # records.rows.first.title.should be == "Late Baroque Towns of the Val di Noto (South-Eastern Sicily)"
55
- # records.rows.first.latitude.should be > 0
56
- # records.rows.first.longitude.should be > 0
57
- # records.rows.first.description.should match /Val di Noto \(English: Vallum of Noto\) is a geographical area of south east Sicily/
58
- # records.rows.first.region.should be == "Provinces of Catania, Ragusa, and Syracuse, Sicily"
59
- # records.rows.first.type.should be == "cultural"
60
- # records.rows.first.endangered_reason.should be_nil
61
- # records.rows.first.edited_region.should be == "Provinces of Catania, Ragusa, and Syracuse, Sicily"
62
- # records.rows.first.endangered_year.should be_nil
63
- # records.rows.first.external_links.should be_empty
64
- # records.rows.first.wikipedia_link.should be == "http://en.wikipedia.org/wiki/Val_di_Noto"
65
- # records.rows.first.comments.should be_nil
66
- # records.rows.first.criteria.should be == "[i],[ii],[iv],[v]"
67
- # records.rows.first.iso_code.should be == "IT"
68
- # records.rows.first.size.should be == 1130000.0
69
- # records.rows.first.name.should be == "Late Baroque Towns of the Val di Noto (South-Eastern Sicily)"
70
- # records.rows.first.country.should be == "Italy"
71
- # records.rows.first.whs_site_id.should be == 1024
72
- # records.rows.first.date_of_inscription.should be == "2002"
73
- # records.rows.first.whs_source_page.should be == "http://whc.unesco.org/en/list/1024"
74
- # records.rows.first.created_at.should_not be_nil
75
- # records.rows.first.updated_at.should_not be_nil
76
- #
77
- # end
41
+ it "should create a table from a csv file" do
42
+
43
+ table = CartoDB::Connection.create_table 'whs_sites', File.open("#{File.dirname(__FILE__)}/support/whs_features.csv", 'r')
44
+
45
+ table.should_not be_nil
46
+ table[:id].should be > 0
47
+ table = CartoDB::Connection.table table[:name]
48
+ table.schema.should have(24).items
49
+
50
+ records = CartoDB::Connection.records table[:name]
51
+ records.should_not be_nil
52
+ records.rows.should have(10).whs_sites
53
+
54
+ records.rows.first.cartodb_id.should be > 0
55
+ records.rows.first.title.should be == "Aflaj Irrigation Systems of Oman"
56
+ records.rows.first.latitude.should be > 0
57
+ records.rows.first.longitude.should be > 0
58
+ records.rows.first.description.should match /A qanāt \(from Arabic: قناة‎\) \(Iran, Syria and Jordan\) is a water management system used to provide/
59
+ records.rows.first.region.should be == "Dakhiliya, Sharqiya and Batinah Regions"
60
+ records.rows.first.type.should be == "cultural"
61
+ records.rows.first.endangered_reason.should be_empty
62
+ records.rows.first.edited_region.should be == "Dakhiliya, Sharqiya and Batinah Regions"
63
+ records.rows.first.endangered_year.should be_empty
64
+ records.rows.first.external_links.should_not be_empty
65
+ records.rows.first.wikipedia_link.should be == "http://en.wikipedia.org/wiki/Qanat"
66
+ records.rows.first.comments.should be_empty
67
+ records.rows.first.criteria.should be == "[v]"
68
+ records.rows.first.iso_code.should be == "OM"
69
+ records.rows.first.size.should be == 14560000.0
70
+ records.rows.first.name.should be == "Aflaj Irrigation Systems of Oman"
71
+ records.rows.first.country.should be == "Oman"
72
+ records.rows.first.whs_site_id.should be == 1207
73
+ records.rows.first.date_of_inscription.should be == 2006
74
+ records.rows.first.whs_source_page.should be == "http://whc.unesco.org/en/list/1207"
75
+ records.rows.first.created_at.should_not be_nil
76
+ records.rows.first.updated_at.should_not be_nil
77
+
78
+ end
79
+
80
+ it "should import any kind of data file" do
81
+ Dir["#{File.dirname(__FILE__)}/support/data/*"].each do |file|
82
+ table = CartoDB::Connection.create_table File.basename(file, '.*'), File.open(file, 'r')
83
+
84
+ table.should_not be_nil
85
+ table[:id].should be > 0
86
+ table[:name].should_not be_empty
87
+ end
88
+ end
89
+
90
+ it "should create a table with POINT type geometry" do
91
+ table = CartoDB::Connection.create_table 'cartodb_spec', 'point'
92
+
93
+ table.should_not be_nil
94
+ table = CartoDB::Connection.table 'cartodb_spec'
95
+ table.schema.should have(6).items
96
+ table.schema.should include(["cartodb_id", "number"])
97
+ table.schema.should include(["created_at", "date"])
98
+ table.schema.should include(["updated_at", "date"])
99
+ table.schema.should include(["name", "string"])
100
+ table.schema.should include(["description", "string"])
101
+ table.schema.should include(["the_geom", "geometry", "geometry", "point"])
102
+ end
103
+
104
+ it "should create a table with MULTIPOLYGON type geometry" do
105
+ table = CartoDB::Connection.create_table 'cartodb_spec', 'multipolygon'
106
+
107
+ table.should_not be_nil
108
+ table = CartoDB::Connection.table 'cartodb_spec'
109
+ table.schema.should have(6).items
110
+ table.schema.should include(["cartodb_id", "number"])
111
+ table.schema.should include(["created_at", "date"])
112
+ table.schema.should include(["updated_at", "date"])
113
+ table.schema.should include(["name", "string"])
114
+ table.schema.should include(["description", "string"])
115
+ table.schema.should include(["the_geom", "geometry", "geometry", "multipolygon"])
116
+ end
117
+
118
+ it "should rename an existing table" do
119
+ table = CartoDB::Connection.create_table 'cartodb_spec'
120
+
121
+ table.name.should be == 'cartodb_spec'
122
+
123
+ table = CartoDB::Connection.rename_table 'cartodb_spec', 'renamed_cartodb_spec'
124
+ table.name.should be == 'renamed_cartodb_spec'
125
+ end
126
+
127
+ it "should create a table with MULTILINESTRING type geometry" do
128
+ table = CartoDB::Connection.create_table 'cartodb_spec', 'multilinestring'
129
+
130
+ table.should_not be_nil
131
+ table = CartoDB::Connection.table 'cartodb_spec'
132
+ table.schema.should have(6).items
133
+ table.schema.should include(["cartodb_id", "number"])
134
+ table.schema.should include(["created_at", "date"])
135
+ table.schema.should include(["updated_at", "date"])
136
+ table.schema.should include(["name", "string"])
137
+ table.schema.should include(["description", "string"])
138
+ table.schema.should include(["the_geom", "geometry", "geometry", "multilinestring"])
139
+ end
78
140
 
79
141
  it "should add and remove colums in a previously created table" do
80
142
  CartoDB::Connection.create_table 'cartodb_spec'
@@ -127,35 +189,34 @@ describe 'CartoDB client' do
127
189
 
128
190
  it "should insert a row in a table" do
129
191
  table = CartoDB::Connection.create_table 'table #1', [
130
- {:name => 'field1', :type => 'text'},
131
- {:name => 'field2', :type => 'numeric'},
132
- {:name => 'field3', :type => 'date'},
133
- {:name => 'field4', :type => 'boolean'}
134
- ]
192
+ {:name => 'field1', :type => 'text'},
193
+ {:name => 'field2', :type => 'numeric'},
194
+ {:name => 'field3', :type => 'date'},
195
+ {:name => 'field4', :type => 'boolean'}
196
+ ]
135
197
 
136
198
  today = DateTime.now
137
199
 
138
- inserted_row = CartoDB::Connection.insert_row 'table_1', {
200
+ record = CartoDB::Connection.insert_row 'table_1', {
139
201
  'field1' => 'lorem',
140
202
  'field2' => 100.99,
141
203
  'field3' => today,
142
204
  'field4' => true
143
205
  }
144
206
 
145
- record = CartoDB::Connection.row 'table_1', inserted_row.id
146
- record.field1.should == 'lorem'
147
- record.field2.should == 100.99
207
+ record.field1.should == 'lorem'
208
+ record.field2.should == 100.99
148
209
  record.field3.to_date.should == today.to_date
149
- record.field4.should == true
210
+ record.field4.should == true
150
211
  end
151
212
 
152
213
  it "should update a row in a table" do
153
214
  table = CartoDB::Connection.create_table 'table #1', [
154
- {:name => 'field1', :type => 'text'},
155
- {:name => 'field2', :type => 'numeric'},
156
- {:name => 'field3', :type => 'date'},
157
- {:name => 'field4', :type => 'boolean'}
158
- ]
215
+ {:name => 'field1', :type => 'text'},
216
+ {:name => 'field2', :type => 'numeric'},
217
+ {:name => 'field3', :type => 'date'},
218
+ {:name => 'field4', :type => 'boolean'}
219
+ ]
159
220
 
160
221
  today = DateTime.now
161
222
 
@@ -166,15 +227,13 @@ describe 'CartoDB client' do
166
227
  'field4' => true
167
228
  }
168
229
 
169
- CartoDB::Connection.update_row 'table_1', record.id, {
230
+ record = CartoDB::Connection.update_row 'table_1', record.id, {
170
231
  'field1' => 'illum',
171
232
  'field2' => -83.24,
172
233
  'field3' => today + 1,
173
234
  'field4' => false
174
235
  }
175
236
 
176
- record = CartoDB::Connection.row 'table_1', record.id
177
-
178
237
  record.field1.should == 'illum'
179
238
  record.field2.should == -83.24
180
239
  record.field3.to_date.should == (today + 1).to_date
@@ -183,11 +242,11 @@ describe 'CartoDB client' do
183
242
 
184
243
  it "should delete a table's row" do
185
244
  table = CartoDB::Connection.create_table 'table #1', [
186
- {:name => 'field1', :type => 'text'},
187
- {:name => 'field2', :type => 'numeric'},
188
- {:name => 'field3', :type => 'date'},
189
- {:name => 'field4', :type => 'boolean'}
190
- ]
245
+ {:name => 'field1', :type => 'text'},
246
+ {:name => 'field2', :type => 'numeric'},
247
+ {:name => 'field3', :type => 'date'},
248
+ {:name => 'field4', :type => 'boolean'}
249
+ ]
191
250
 
192
251
  today = Time.now
193
252
 
@@ -275,4 +334,24 @@ describe 'CartoDB client' do
275
334
 
276
335
  end
277
336
 
337
+ it 'should escape properly input data in insert queries' do
338
+
339
+ table = CartoDB::Connection.create_table 'table #1', 'multipolygon'
340
+ table.schema.should include(["the_geom", "geometry", "geometry", "multipolygon"])
341
+
342
+ record = CartoDB::Connection.insert_row 'table_1', {
343
+ 'the_geom' => "ST_GeomFromText('MULTIPOLYGON(((95.67764648436992 59.894444919406,90.75577148436992 54.16886220825434,103.41202148436992 56.75874227547269,95.67764648436992 59.894444919406)))', 4326)"
344
+ }
345
+
346
+ record.id.should_not be_nil
347
+ end
348
+
349
+ it 'should allow reserved words in columns names' do
350
+ table = CartoDB::Connection.create_table 'table #1', [{:name => 'class', :type => 'text'}]
351
+ table.schema.should include(["class", "string"])
352
+
353
+ record = CartoDB::Connection.insert_row table.name, :class => 'wadus'
354
+ record.class_.should == 'wadus'
355
+ end
356
+
278
357
  end