cartodb-rb-client 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
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