cartodb-rb-client 0.1.8

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.
Files changed (65) hide show
  1. data/.gitignore +5 -0
  2. data/.rvmrc +2 -0
  3. data/Gemfile +12 -0
  4. data/LICENSE +28 -0
  5. data/README.markdown +324 -0
  6. data/Rakefile +10 -0
  7. data/cartodb-rb-client.gemspec +34 -0
  8. data/lib/cartodb-rb-client/cartodb/client/authorization.rb +58 -0
  9. data/lib/cartodb-rb-client/cartodb/client/cache.rb +14 -0
  10. data/lib/cartodb-rb-client/cartodb/client/connection/base.rb +44 -0
  11. data/lib/cartodb-rb-client/cartodb/client/connection/cartodb.rb +231 -0
  12. data/lib/cartodb-rb-client/cartodb/client/connection/postgres.rb +255 -0
  13. data/lib/cartodb-rb-client/cartodb/client/connection.rb +4 -0
  14. data/lib/cartodb-rb-client/cartodb/client/error.rb +68 -0
  15. data/lib/cartodb-rb-client/cartodb/client/utils.rb +20 -0
  16. data/lib/cartodb-rb-client/cartodb/client.rb +4 -0
  17. data/lib/cartodb-rb-client/cartodb/helpers/sql_helper.rb +30 -0
  18. data/lib/cartodb-rb-client/cartodb/helpers.rb +1 -0
  19. data/lib/cartodb-rb-client/cartodb/init.rb +30 -0
  20. data/lib/cartodb-rb-client/cartodb/libs/object.rb +15 -0
  21. data/lib/cartodb-rb-client/cartodb/libs/string.rb +116 -0
  22. data/lib/cartodb-rb-client/cartodb/libs.rb +2 -0
  23. data/lib/cartodb-rb-client/cartodb/model/base.rb +20 -0
  24. data/lib/cartodb-rb-client/cartodb/model/constants.rb +30 -0
  25. data/lib/cartodb-rb-client/cartodb/model/defaults.rb +15 -0
  26. data/lib/cartodb-rb-client/cartodb/model/geo.rb +73 -0
  27. data/lib/cartodb-rb-client/cartodb/model/getters.rb +79 -0
  28. data/lib/cartodb-rb-client/cartodb/model/persistence.rb +69 -0
  29. data/lib/cartodb-rb-client/cartodb/model/query.rb +66 -0
  30. data/lib/cartodb-rb-client/cartodb/model/schema.rb +111 -0
  31. data/lib/cartodb-rb-client/cartodb/model/scope.rb +163 -0
  32. data/lib/cartodb-rb-client/cartodb/model/setters.rb +42 -0
  33. data/lib/cartodb-rb-client/cartodb/model.rb +11 -0
  34. data/lib/cartodb-rb-client/cartodb/types/metadata.rb +89 -0
  35. data/lib/cartodb-rb-client/cartodb/types/pg_result.rb +17 -0
  36. data/lib/cartodb-rb-client/cartodb/types.rb +2 -0
  37. data/lib/cartodb-rb-client/cartodb.rb +6 -0
  38. data/lib/cartodb-rb-client/install_utils.rb +19 -0
  39. data/lib/cartodb-rb-client/version.rb +7 -0
  40. data/lib/cartodb-rb-client.rb +17 -0
  41. data/run_tests.sh +6 -0
  42. data/spec/client_spec.rb +278 -0
  43. data/spec/model/data_spec.rb +130 -0
  44. data/spec/model/metadata_spec.rb +116 -0
  45. data/spec/model/scopes_spec.rb +171 -0
  46. data/spec/spec_helper.rb +28 -0
  47. data/spec/support/cartodb_config.yml +15 -0
  48. data/spec/support/cartodb_factories.rb +33 -0
  49. data/spec/support/cartodb_helpers.rb +14 -0
  50. data/spec/support/cartodb_models.rb +22 -0
  51. data/spec/support/database.yml +5 -0
  52. data/spec/support/shp/cereal.dbf +0 -0
  53. data/spec/support/shp/cereal.shp +0 -0
  54. data/spec/support/shp/cereal.shx +0 -0
  55. data/spec/support/shp/cereal.zip +0 -0
  56. data/spec/support/shp/parcelas.dbf +0 -0
  57. data/spec/support/shp/parcelas.shp +0 -0
  58. data/spec/support/shp/parcelas.shx +0 -0
  59. data/spec/support/shp/parcelas.zip +0 -0
  60. data/spec/support/shp/zonas.dbf +0 -0
  61. data/spec/support/shp/zonas.shp +0 -0
  62. data/spec/support/shp/zonas.shx +0 -0
  63. data/spec/support/shp/zonas.zip +0 -0
  64. data/spec/support/whs_features.csv +33425 -0
  65. metadata +311 -0
@@ -0,0 +1,163 @@
1
+ module CartoDB
2
+ module Model
3
+ class Scope
4
+ extend Forwardable
5
+ include CartoDB::Model::Constants
6
+
7
+ def_delegators :@model, :connection, :table_name, :cartodb_table
8
+
9
+ def initialize(model)
10
+ @model = model
11
+ @records = nil
12
+ @custom_fields = nil
13
+ @rows_per_page = nil
14
+ end
15
+
16
+ def to_a
17
+ @records ||= begin
18
+
19
+ results = connection.query build_sql
20
+
21
+ if results && results.rows
22
+ results.rows.map{|r| @model.new(r)}
23
+ else
24
+ []
25
+ end
26
+ rescue Exception => e
27
+ []
28
+ end
29
+
30
+ end
31
+ alias all to_a
32
+
33
+ def length
34
+ to_a.length
35
+ end
36
+ alias size length
37
+ alias count length
38
+
39
+ def select(*fields)
40
+ case fields
41
+ when String
42
+ @custom_fields = fields
43
+ when Array
44
+ @custom_fields = fields.join(', ')
45
+ end
46
+
47
+ self
48
+ end
49
+
50
+ def where(attributes = nil, *rest)
51
+ @records = nil
52
+ return all if attributes.nil? || (attributes.is_a?(Hash) && attributes.empty?) || (attributes.is_a?(Integer) && attributes <= 0)
53
+
54
+ if attributes.is_a?(Integer) || (attributes.length == 1 && (attributes[:cartodb_id] || attributes[:id]))
55
+ row_id = attributes.is_a?(Integer) ? attributes : (attributes[:cartodb_id] || attributes[:id])
56
+ return @model.new(connection.row(table_name, row_id))
57
+ end
58
+
59
+ create_filters(attributes, rest)
60
+
61
+ self
62
+ end
63
+
64
+ def page(page_number)
65
+ @page = page_number
66
+
67
+ self
68
+ end
69
+
70
+ def per_page(ammount)
71
+ @rows_per_page = ammount
72
+
73
+ self
74
+ end
75
+
76
+ def order(order_clause)
77
+ @order_clauses ||= []
78
+ @order_clauses << order_clause
79
+
80
+ self
81
+ end
82
+
83
+ def method_missing(method, *args, &block)
84
+ if Array.method_defined?(method)
85
+ to_a.send(method, *args, &block)
86
+ else
87
+ super
88
+ end
89
+ end
90
+ protected :method_missing
91
+
92
+ def filters
93
+ @filters ||= []
94
+ end
95
+ private :filters
96
+
97
+ def build_sql
98
+ select = build_select
99
+ from = build_from
100
+ where = build_where
101
+ order = build_order
102
+ pagination = build_pagination
103
+
104
+ sql = "#{select} #{from} #{where} #{order} #{pagination}"
105
+ end
106
+ alias to_sql build_sql
107
+
108
+ def build_select
109
+ columns = @custom_fields || cartodb_table.schema.map{|c| c[0]}.join(', ')
110
+ select = "SELECT #{columns}"
111
+ end
112
+ private :build_select
113
+
114
+ def build_from
115
+ from = "FROM #{table_name}"
116
+ end
117
+ private :build_from
118
+
119
+ def build_where
120
+ where = "WHERE #{filters.join(' AND ')}" if filters && filters.any?
121
+ end
122
+ private :build_where
123
+
124
+ def build_pagination
125
+ offset = (current_page - 1) * rows_per_page
126
+ pagination = "LIMIT #{rows_per_page} OFFSET #{offset}"
127
+ end
128
+ private :build_pagination
129
+
130
+ def build_order
131
+ order = "ORDER BY #{order_clauses.join(', ')}" unless order_clauses.nil? || order_clauses.empty?
132
+ end
133
+ private :build_order
134
+
135
+ def create_filters(attributes, values)
136
+ case attributes
137
+ when Hash
138
+ filters << attributes.to_a.map{|i| "#{table_name}.#{i.first} = #{i.last}"}.join(' AND ')
139
+ when String
140
+ values = values.flatten
141
+ filters << attributes.gsub(/[\?]/){|r| values.shift}
142
+ end
143
+ end
144
+ private :create_filters
145
+
146
+ def current_page
147
+ @page || 1
148
+ end
149
+ private :current_page
150
+
151
+ def rows_per_page
152
+ @rows_per_page || DEFAULT_ROWS_PER_PAGE
153
+ end
154
+ private :rows_per_page
155
+
156
+ def order_clauses
157
+ @order_clauses || []
158
+ end
159
+ private :order_clauses
160
+
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,42 @@
1
+ module CartoDB
2
+ module Model
3
+ module Setters
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+
10
+ def cartodb_table_name(table_name)
11
+ @table_name = table_name
12
+ end
13
+
14
+ def cartodb_table=(table)
15
+ @cartodb_table = table
16
+ end
17
+
18
+ def columns=(columns)
19
+ @columns = columns
20
+ end
21
+
22
+ end
23
+
24
+ def cartodb_table=(table)
25
+ self.class.cartodb_table = table
26
+ end
27
+
28
+ def attributes=(attributes)
29
+ @attributes = prepare_geo_attributes(attributes)
30
+ end
31
+
32
+ # def method_missing(name, *args, &block)
33
+ # if args.count == 1 && block.nil? && name.to_s.ends_with?('=') && column_names.include?(name.to_s[0..-2])
34
+ # attributes[name.to_s[0..-2].to_sym] = args.first
35
+ # else
36
+ # super
37
+ # end
38
+ # end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,11 @@
1
+ require 'forwardable'
2
+ require 'active_support/core_ext/string'
3
+ require 'cartodb-rb-client/cartodb/model/constants'
4
+ require 'cartodb-rb-client/cartodb/model/geo'
5
+ require 'cartodb-rb-client/cartodb/model/getters'
6
+ require 'cartodb-rb-client/cartodb/model/setters'
7
+ require 'cartodb-rb-client/cartodb/model/schema'
8
+ require 'cartodb-rb-client/cartodb/model/persistence'
9
+ require 'cartodb-rb-client/cartodb/model/query'
10
+ require 'cartodb-rb-client/cartodb/model/base'
11
+ require 'cartodb-rb-client/cartodb/model/scope'
@@ -0,0 +1,89 @@
1
+ module CartoDB
2
+ module Types
3
+ class Metadata < Hash
4
+
5
+ class << self
6
+ def from_hash(hash = {})
7
+ metadata = self.new
8
+
9
+ hash.each do |key, value|
10
+ metadata[key.to_sym] = value
11
+ end
12
+ metadata
13
+ end
14
+ end
15
+
16
+ def []=(key, value)
17
+ if key.to_s.eql?('the_geom')
18
+ value = _geometry_features(value)
19
+ else
20
+ value = cast_value(value) unless CartoDB::Settings[:type_casting] == false
21
+ end
22
+
23
+ self.class.send :define_method, "#{key}" do
24
+ self[key.to_sym]
25
+ end
26
+
27
+ self.class.send :define_method, "#{key}=" do |value|
28
+ self[key.to_sym] = value
29
+ end
30
+
31
+ super(key, value)
32
+ end
33
+
34
+ def method_missing(name, *args, &block)
35
+ if name.to_s.end_with?('=') && args.size == 1
36
+ key = name.to_s[0...-1]
37
+ self[key.to_sym] = args[0]
38
+ else
39
+ super
40
+ end
41
+ end
42
+
43
+ def _geometry_features(the_geom)
44
+
45
+ begin
46
+ the_geom = RGeo::WKRep::WKBParser.new(RGeo::Geographic.spherical_factory(:srid => 4326), :support_ewkb => true).parse(the_geom)
47
+ rescue
48
+ begin
49
+ the_geom = RGeo::GeoJSON.decode(the_geom, :json_parser => :json, :geo_factory => RGeo::Geographic.spherical_factory(:srid => 4326))
50
+ rescue
51
+ end
52
+ end
53
+
54
+ case the_geom
55
+ when RGeo::Feature::Point || RGeo::Geographic::SphericalPointImpl
56
+ self.class.send :define_method, :latitude do
57
+ self.the_geom ? self.the_geom.y : nil
58
+ end
59
+
60
+ self.class.send :define_method, :longitude do
61
+ self.the_geom ? self.the_geom.x : nil
62
+ end
63
+ end
64
+
65
+ the_geom
66
+ end
67
+ private :_geometry_features
68
+
69
+ def cast_value(value)
70
+ return nil if value.nil?
71
+ return true if value.eql?('t')
72
+ return false if value.eql?('f')
73
+
74
+ begin
75
+ value = Float(value)
76
+ return value == value.floor ? value.to_i : value
77
+ rescue
78
+ end
79
+
80
+ return DateTime.strptime(value, '%Y-%m-%d') rescue
81
+ return DateTime.strptime(value, '%d-%m-%Y') rescue
82
+
83
+ value
84
+ end
85
+ private :cast_value
86
+
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,17 @@
1
+ class PGresult
2
+ def empty?
3
+ to_a.empty?
4
+ end
5
+
6
+ def items
7
+ to_a
8
+ end
9
+
10
+ def sample
11
+ to_a.sample
12
+ end
13
+
14
+ def size
15
+ to_a.size
16
+ end
17
+ end
@@ -0,0 +1,2 @@
1
+ require 'cartodb-rb-client/cartodb/types/metadata'
2
+ require 'cartodb-rb-client/cartodb/types/pg_result'
@@ -0,0 +1,6 @@
1
+ require 'cartodb-rb-client/cartodb/init'
2
+ require 'cartodb-rb-client/cartodb/libs'
3
+ require 'cartodb-rb-client/cartodb/helpers'
4
+ require 'cartodb-rb-client/cartodb/client'
5
+ require 'cartodb-rb-client/cartodb/types'
6
+ require 'cartodb-rb-client/cartodb/model'
@@ -0,0 +1,19 @@
1
+ module InstallUtils
2
+ def postgresql_installed?
3
+
4
+ return false unless system 'which pg_config > /dev/null'
5
+
6
+ pg_config_file = %x[cat `which pg_config`]
7
+ pgconfig_dirs_keys = %w(BINDIR INCLUDEDIR PKGINCLUDEDIR INCLUDEDIR-SERVER LIBDIR PKGLIBDIR SHAREDIR PGXS)
8
+
9
+ dirs_to_check = Hash[*%x[`which pg_config`].split("\n").map{|o| o.split(' = ')}.select{|o| pgconfig_dirs_keys.include?(o.first)}.flatten]
10
+
11
+ if dirs_to_check.keys.count == pgconfig_dirs_keys.count
12
+ return dirs_to_check.values.inject(true){|exists, dir| exists && File.exists?(dir)}
13
+ end
14
+
15
+ false
16
+ end
17
+ end
18
+
19
+ include InstallUtils
@@ -0,0 +1,7 @@
1
+ module Cartodb
2
+ module Rb
3
+ module Client
4
+ VERSION = "0.1.8"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'ostruct'
5
+ require 'oauth'
6
+ require 'typhoeus'
7
+ require 'mime/types'
8
+ require 'active_support/core_ext/hash/slice'
9
+ require 'rgeo'
10
+ require 'rgeo/geo_json'
11
+ require 'pg'
12
+ require 'json/ext'
13
+
14
+ require 'cartodb-rb-client/cartodb'
15
+
16
+ OpenSSL::SSL.send :remove_const, :VERIFY_PEER
17
+ OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
data/run_tests.sh ADDED
@@ -0,0 +1,6 @@
1
+ #!/bin/sh
2
+ rvm 1.8.7@cartodb-rb-client
3
+ bundle install
4
+ rvm 1.9.2@cartodb-rb-client
5
+ bundle install
6
+ rvm 1.8.7@cartodb-rb-client,1.9.2@cartodb-rb-client rake spec
@@ -0,0 +1,278 @@
1
+ # coding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ describe 'CartoDB client' do
5
+
6
+ it "should create a table and get its table definition" do
7
+
8
+ table = CartoDB::Connection.create_table 'cartodb_spec'
9
+
10
+ table.should_not be_nil
11
+ table = CartoDB::Connection.table 'cartodb_spec'
12
+ table.schema.should have(6).items
13
+ table.schema.should include(["cartodb_id", "number"])
14
+ table.schema.should include(["created_at", "date"])
15
+ table.schema.should include(["updated_at", "date"])
16
+ table.schema.should include(["name", "string"])
17
+ table.schema.should include(["description", "string"])
18
+ table.schema.should include(["the_geom", "geometry", "geometry", "point"])
19
+ end
20
+
21
+ it "should create a table forcing the schema and get its table definition" do
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
+ ]
28
+
29
+ table.should_not be_nil
30
+ table = CartoDB::Connection.table 'cartodb_spec'
31
+ table.schema.should have(7).items
32
+ table.schema.should include(["cartodb_id", "number"])
33
+ table.schema.should include(["created_at", "date"])
34
+ table.schema.should include(["updated_at", "date"])
35
+ table.schema.should include(["field1", "string"])
36
+ table.schema.should include(["field2", "number"])
37
+ table.schema.should include(["field3", "date"])
38
+ table.schema.should include(["field4", "boolean"])
39
+ end
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
78
+
79
+ it "should add and remove colums in a previously created table" do
80
+ CartoDB::Connection.create_table 'cartodb_spec'
81
+ CartoDB::Connection.add_column 'cartodb_spec', 'field1', 'text'
82
+ CartoDB::Connection.add_column 'cartodb_spec', 'field2', 'numeric'
83
+ CartoDB::Connection.add_column 'cartodb_spec', 'field3', 'date'
84
+
85
+ table = CartoDB::Connection.table 'cartodb_spec'
86
+ table.schema.should have(9).items
87
+ table.schema.should include(["field1", "string"])
88
+ table.schema.should include(["field2", "number"])
89
+ table.schema.should include(["field3", "date"])
90
+
91
+ CartoDB::Connection.drop_column 'cartodb_spec', 'field3'
92
+ table = CartoDB::Connection.table 'cartodb_spec'
93
+ table.schema.should have(8).items
94
+ table.schema.should_not include(["field3", "date"])
95
+ end
96
+
97
+ it "should change a previously created column" do
98
+ CartoDB::Connection.create_table 'cartodb_spec', [{:name => 'field1', :type => 'text'}]
99
+ CartoDB::Connection.change_column 'cartodb_spec', "field1", "changed_field", "numeric"
100
+ table = CartoDB::Connection.table 'cartodb_spec'
101
+ table.schema.should_not include(["field1", "string"])
102
+ table.schema.should include(["changed_field", "number"])
103
+ end
104
+
105
+ it "should return user's table list" do
106
+ table_1 = CartoDB::Connection.create_table 'table #1'
107
+ table_2 = CartoDB::Connection.create_table 'table #2'
108
+
109
+ tables_list = CartoDB::Connection.tables
110
+ tables_list.tables.should have(2).items
111
+ tables_list.tables.map(&:name).should include(table_1.name)
112
+ tables_list.tables.map(&:name).should include(table_2.name)
113
+ end
114
+
115
+ it "should drop a table" do
116
+ table_1 = CartoDB::Connection.create_table 'table #1'
117
+ table_2 = CartoDB::Connection.create_table 'table #2'
118
+ table_3 = CartoDB::Connection.create_table 'table #3'
119
+
120
+ CartoDB::Connection.drop_table 'table_2'
121
+
122
+ tables_list = CartoDB::Connection.tables
123
+ tables_list.tables.should have(2).items
124
+ tables_list.tables.map(&:name).should include(table_1.name)
125
+ tables_list.tables.map(&:name).should include(table_3.name)
126
+ end
127
+
128
+ it "should insert a row in a table" do
129
+ 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
+ ]
135
+
136
+ today = DateTime.now
137
+
138
+ inserted_row = CartoDB::Connection.insert_row 'table_1', {
139
+ 'field1' => 'lorem',
140
+ 'field2' => 100.99,
141
+ 'field3' => today,
142
+ 'field4' => true
143
+ }
144
+
145
+ record = CartoDB::Connection.row 'table_1', inserted_row.id
146
+ record.field1.should == 'lorem'
147
+ record.field2.should == 100.99
148
+ record.field3.to_date.should == today.to_date
149
+ record.field4.should == true
150
+ end
151
+
152
+ it "should update a row in a table" do
153
+ 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
+ ]
159
+
160
+ today = DateTime.now
161
+
162
+ record = CartoDB::Connection.insert_row 'table_1', {
163
+ 'field1' => 'lorem',
164
+ 'field2' => 100.99,
165
+ 'field3' => today,
166
+ 'field4' => true
167
+ }
168
+
169
+ CartoDB::Connection.update_row 'table_1', record.id, {
170
+ 'field1' => 'illum',
171
+ 'field2' => -83.24,
172
+ 'field3' => today + 1,
173
+ 'field4' => false
174
+ }
175
+
176
+ record = CartoDB::Connection.row 'table_1', record.id
177
+
178
+ record.field1.should == 'illum'
179
+ record.field2.should == -83.24
180
+ record.field3.to_date.should == (today + 1).to_date
181
+ record.field4.should == false
182
+ end
183
+
184
+ it "should delete a table's row" do
185
+ 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
+ ]
191
+
192
+ today = Time.now
193
+
194
+ record = CartoDB::Connection.insert_row 'table_1', {
195
+ 'field1' => 'lorem',
196
+ 'field2' => 100.99,
197
+ 'field3' => today,
198
+ 'field4' => true
199
+ }
200
+
201
+ CartoDB::Connection.delete_row 'table_1', record.id
202
+
203
+ records = CartoDB::Connection.records 'table_1'
204
+
205
+ records.name.should be == 'table_1'
206
+ records.total_rows.should == 0
207
+ records.rows.should be_empty
208
+ end
209
+
210
+ it "should execute a select query and return results" do
211
+ table = CartoDB::Connection.create_table 'table #1'
212
+
213
+ 10.times do
214
+ row = CartoDB::Connection.insert_row 'table_1', {
215
+ 'name' => String.random(15),
216
+ 'description' => String.random(200),
217
+ 'the_geom' => RgeoFactory.point(-3.69962, 40.42222)
218
+ }
219
+
220
+ end
221
+ results = CartoDB::Connection.query("SELECT * FROM table_1")
222
+ results.should_not be_nil
223
+ results.time.should be > 0
224
+ results.total_rows.should == 10
225
+ results.rows.should have(10).items
226
+ results.rows.each do |row|
227
+ row.cartodb_id.should be > 0
228
+ row.name.should_not be_empty
229
+ row.latitude.should be == 40.42222
230
+ row.longitude.should be == -3.6996199999999817
231
+ row.description.should_not be_empty
232
+ row.created_at.should_not be_nil
233
+ row.updated_at.should_not be_nil
234
+ end
235
+ end
236
+
237
+ it "should get a table by its name" do
238
+ created_table = CartoDB::Connection.create_table 'table_with_name'
239
+
240
+ table = CartoDB::Connection.table 'table_with_name'
241
+ table.should_not be_nil
242
+ table.name.should be == created_table.name
243
+ end
244
+
245
+ it "should return nil when requesting a table which does not exists" do
246
+ expect{CartoDB::Connection.table('non_existing_table')}.to raise_error(CartoDB::Client::Error)
247
+ end
248
+
249
+ it "should return errors on invalid queries" do
250
+ expect{results = CartoDB::Connection.query("SELECT 1 FROM non_existing_table")}.to raise_error(CartoDB::Client::Error, /relation "non_existing_table" does not exist/)
251
+ end
252
+
253
+ it "should paginate records" do
254
+ table = CartoDB::Connection.create_table 'table #1'
255
+
256
+ 50.times do
257
+ CartoDB::Connection.insert_row 'table_1', {
258
+ 'name' => String.random(15),
259
+ 'description' => String.random(200),
260
+ 'the_geom' => RgeoFactory.point(rand(180), rand(90))
261
+ }
262
+ end
263
+
264
+ records = CartoDB::Connection.records 'table_1', :page => 0, :rows_per_page => 20
265
+ records.total_rows.should be == 50
266
+ records.rows.should have(20).records
267
+ records.rows.first.cartodb_id.should be == 1
268
+ records.rows.last.cartodb_id.should be == 20
269
+
270
+ records = CartoDB::Connection.records 'table_1', :page => 1, :rows_per_page => 20
271
+ records.total_rows.should be == 50
272
+ records.rows.should have(20).records
273
+ records.rows.first.cartodb_id.should be == 21
274
+ records.rows.last.cartodb_id.should be == 40
275
+
276
+ end
277
+
278
+ end