cartodb-rb-client-rails-322 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. data/.gitignore +5 -0
  2. data/.rvmrc +1 -0
  3. data/.travis.yml +15 -0
  4. data/Gemfile +15 -0
  5. data/LICENSE +28 -0
  6. data/README.markdown +365 -0
  7. data/Rakefile +10 -0
  8. data/cartodb-rb-client.gemspec +34 -0
  9. data/lib/cartodb-rb-client.rb +18 -0
  10. data/lib/cartodb-rb-client/cartodb.rb +6 -0
  11. data/lib/cartodb-rb-client/cartodb/client.rb +4 -0
  12. data/lib/cartodb-rb-client/cartodb/client/authorization.rb +92 -0
  13. data/lib/cartodb-rb-client/cartodb/client/cache.rb +14 -0
  14. data/lib/cartodb-rb-client/cartodb/client/connection.rb +4 -0
  15. data/lib/cartodb-rb-client/cartodb/client/connection/base.rb +44 -0
  16. data/lib/cartodb-rb-client/cartodb/client/connection/cartodb.rb +280 -0
  17. data/lib/cartodb-rb-client/cartodb/client/connection/postgres.rb +255 -0
  18. data/lib/cartodb-rb-client/cartodb/client/error.rb +68 -0
  19. data/lib/cartodb-rb-client/cartodb/client/utils.rb +20 -0
  20. data/lib/cartodb-rb-client/cartodb/helpers.rb +1 -0
  21. data/lib/cartodb-rb-client/cartodb/helpers/sql_helper.rb +36 -0
  22. data/lib/cartodb-rb-client/cartodb/init.rb +30 -0
  23. data/lib/cartodb-rb-client/cartodb/libs.rb +2 -0
  24. data/lib/cartodb-rb-client/cartodb/libs/object.rb +15 -0
  25. data/lib/cartodb-rb-client/cartodb/libs/string.rb +116 -0
  26. data/lib/cartodb-rb-client/cartodb/model.rb +11 -0
  27. data/lib/cartodb-rb-client/cartodb/model/base.rb +20 -0
  28. data/lib/cartodb-rb-client/cartodb/model/constants.rb +30 -0
  29. data/lib/cartodb-rb-client/cartodb/model/defaults.rb +15 -0
  30. data/lib/cartodb-rb-client/cartodb/model/geo.rb +101 -0
  31. data/lib/cartodb-rb-client/cartodb/model/getters.rb +75 -0
  32. data/lib/cartodb-rb-client/cartodb/model/persistence.rb +69 -0
  33. data/lib/cartodb-rb-client/cartodb/model/query.rb +66 -0
  34. data/lib/cartodb-rb-client/cartodb/model/schema.rb +121 -0
  35. data/lib/cartodb-rb-client/cartodb/model/scope.rb +163 -0
  36. data/lib/cartodb-rb-client/cartodb/model/setters.rb +37 -0
  37. data/lib/cartodb-rb-client/cartodb/types.rb +2 -0
  38. data/lib/cartodb-rb-client/cartodb/types/metadata.rb +97 -0
  39. data/lib/cartodb-rb-client/cartodb/types/pg_result.rb +17 -0
  40. data/lib/cartodb-rb-client/install_utils.rb +19 -0
  41. data/lib/cartodb-rb-client/version.rb +7 -0
  42. data/run_tests.sh +6 -0
  43. data/spec/client_spec.rb +357 -0
  44. data/spec/fixtures/cassettes/CartoDB_client/should_add_and_remove_colums_in_a_previously_created_table.yml +635 -0
  45. data/spec/fixtures/cassettes/CartoDB_client/should_allow_reserved_words_in_columns_names.yml +284 -0
  46. data/spec/fixtures/cassettes/CartoDB_client/should_change_a_previously_created_column.yml +362 -0
  47. data/spec/fixtures/cassettes/CartoDB_client/should_create_a_table_and_get_its_table_definition.yml +1634 -0
  48. data/spec/fixtures/cassettes/CartoDB_client/should_create_a_table_forcing_the_schema_and_get_its_table_definition.yml +298 -0
  49. data/spec/fixtures/cassettes/CartoDB_client/should_create_a_table_from_a_csv_file.yml +2947 -0
  50. data/spec/fixtures/cassettes/CartoDB_client/should_create_a_table_with_MULTILINESTRING_type_geometry.yml +299 -0
  51. data/spec/fixtures/cassettes/CartoDB_client/should_create_a_table_with_MULTIPOLYGON_type_geometry.yml +298 -0
  52. data/spec/fixtures/cassettes/CartoDB_client/should_create_a_table_with_POINT_type_geometry.yml +580 -0
  53. data/spec/fixtures/cassettes/CartoDB_client/should_delete_a_table_s_row.yml +410 -0
  54. data/spec/fixtures/cassettes/CartoDB_client/should_drop_a_table.yml +380 -0
  55. data/spec/fixtures/cassettes/CartoDB_client/should_escape_properly_input_data_in_insert_queries.yml +295 -0
  56. data/spec/fixtures/cassettes/CartoDB_client/should_execute_a_select_query_and_return_results.yml +987 -0
  57. data/spec/fixtures/cassettes/CartoDB_client/should_get_a_table_by_its_name.yml +298 -0
  58. data/spec/fixtures/cassettes/CartoDB_client/should_import_any_kind_of_data_file.yml +6951 -0
  59. data/spec/fixtures/cassettes/CartoDB_client/should_insert_a_row_in_a_table.yml +357 -0
  60. data/spec/fixtures/cassettes/CartoDB_client/should_paginate_records.yml +3642 -0
  61. data/spec/fixtures/cassettes/CartoDB_client/should_rename_an_existing_table.yml +299 -0
  62. data/spec/fixtures/cassettes/CartoDB_client/should_return_errors_on_invalid_queries.yml +132 -0
  63. data/spec/fixtures/cassettes/CartoDB_client/should_return_nil_when_requesting_a_table_which_does_not_exists.yml +218 -0
  64. data/spec/fixtures/cassettes/CartoDB_client/should_return_user_s_table_list.yml +244 -0
  65. data/spec/fixtures/cassettes/CartoDB_client/should_update_a_row_in_a_table.yml +347 -0
  66. data/spec/fixtures/cassettes/CartoDB_model_data_methods/should_destroy_a_previously_created_record.yml +1920 -0
  67. data/spec/fixtures/cassettes/CartoDB_model_data_methods/should_initialize_attributes_of_the_model_without_persisting_them.yml +963 -0
  68. data/spec/fixtures/cassettes/CartoDB_model_data_methods/should_persist_into_cartodb_using_the_save_method.yml +1946 -0
  69. data/spec/fixtures/cassettes/CartoDB_model_data_methods/should_persist_into_cartodb_using_the_static_create_method.yml +1796 -0
  70. data/spec/fixtures/cassettes/CartoDB_model_data_methods/should_save_polygons_in_different_formats.yml +1801 -0
  71. data/spec/fixtures/cassettes/CartoDB_model_data_methods/should_update_an_existing_record.yml +2856 -0
  72. data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_add_more_columns_if_the_table_previously_exists.yml +1509 -0
  73. data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_contain_an_array_of_columns.yml +2007 -0
  74. data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_create_a_table_with_custom_name_if_specified.yml +357 -0
  75. data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_create_model_with_custom_data_types_columns.yml +565 -0
  76. data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_create_model_with_polygon_type_geometry_columns.yml +493 -0
  77. data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_create_the_table_in_cartodb_if_it_doesn_t_exists.yml +1048 -0
  78. data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_have_a_valid_CartoDB_Client_instance_as_a_connection_object.yml +971 -0
  79. data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_have_a_valid_table_name.yml +970 -0
  80. data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_return_only_data_columns.yml +1096 -0
  81. data/spec/fixtures/cassettes/CartoDB_model_scopes/should_allow_to_select_the_specified_fiels.yml +25828 -0
  82. data/spec/fixtures/cassettes/CartoDB_model_scopes/should_count_all_records.yml +22401 -0
  83. data/spec/fixtures/cassettes/CartoDB_model_scopes/should_find_a_record_by_its_id.yml +21852 -0
  84. data/spec/fixtures/cassettes/CartoDB_model_scopes/should_order_results.yml +23701 -0
  85. data/spec/fixtures/cassettes/CartoDB_model_scopes/should_paginate_results.yml +35644 -0
  86. data/spec/fixtures/cassettes/CartoDB_model_scopes/should_return_all_records_paginated.yml +23699 -0
  87. data/spec/fixtures/cassettes/CartoDB_model_scopes/should_search_records_by_certain_filters.yml +7080 -0
  88. data/spec/fixtures/cassettes/cartodb_spec_models.yml +3409 -0
  89. data/spec/fixtures/cassettes/clean_tables.yml +224 -0
  90. data/spec/model/data_spec.rb +157 -0
  91. data/spec/model/metadata_spec.rb +124 -0
  92. data/spec/model/scopes_spec.rb +171 -0
  93. data/spec/model_specs_helper.rb +2 -0
  94. data/spec/spec_helper.rb +54 -0
  95. data/spec/support/cartodb_config.yml +11 -0
  96. data/spec/support/cartodb_config.yml.sample +16 -0
  97. data/spec/support/cartodb_factories.rb +33 -0
  98. data/spec/support/cartodb_helpers.rb +14 -0
  99. data/spec/support/cartodb_models.rb +29 -0
  100. data/spec/support/data/110m-glaciated-areas.zip +0 -0
  101. data/spec/support/data/CartoDB_csv_export.zip +0 -0
  102. data/spec/support/data/CartoDB_shp_export.zip +0 -0
  103. data/spec/support/data/rmnp.kml +51 -0
  104. data/spec/support/data/states.kml.zip +0 -0
  105. data/spec/support/database.yml +5 -0
  106. data/spec/support/shp/cereal.dbf +0 -0
  107. data/spec/support/shp/cereal.shp +0 -0
  108. data/spec/support/shp/cereal.shx +0 -0
  109. data/spec/support/shp/cereal.zip +0 -0
  110. data/spec/support/shp/parcelas.dbf +0 -0
  111. data/spec/support/shp/parcelas.shp +0 -0
  112. data/spec/support/shp/parcelas.shx +0 -0
  113. data/spec/support/shp/parcelas.zip +0 -0
  114. data/spec/support/shp/zonas.dbf +0 -0
  115. data/spec/support/shp/zonas.shp +0 -0
  116. data/spec/support/shp/zonas.shx +0 -0
  117. data/spec/support/shp/zonas.zip +0 -0
  118. data/spec/support/whs_features.csv +315 -0
  119. data/spec/support/whs_features.csv.zip +0 -0
  120. data/spec/support/whs_features_temp.csv +315 -0
  121. metadata +400 -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,37 @@
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
+ def geometry_type=(geometry_type)
23
+ @geometry_type = geometry_type
24
+ end
25
+ end
26
+
27
+ def cartodb_table=(table)
28
+ self.class.cartodb_table = table
29
+ end
30
+
31
+ def attributes=(attributes)
32
+ @attributes = prepare_geo_attributes(attributes)
33
+ end
34
+
35
+ end
36
+ end
37
+ 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,97 @@
1
+ module CartoDB
2
+ module Types
3
+ class Metadata < Hash
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
+
11
+ class << self
12
+ def from_hash(hash = {})
13
+ metadata = self.new
14
+
15
+ hash.each do |key, value|
16
+ metadata[key.to_sym] = value
17
+ end
18
+ metadata
19
+ end
20
+ end
21
+
22
+ def []=(key, value)
23
+ key = :"#{key}_" if RESERVED_WORDS.include?(key.to_s)
24
+
25
+ if key.to_s.eql?('the_geom')
26
+ value = _geometry_features(value)
27
+ else
28
+ value = cast_value(value) unless CartoDB::Settings[:type_casting] == false
29
+ end
30
+
31
+ self.class.send :define_method, "#{key}" do
32
+ self[key.to_sym]
33
+ end
34
+
35
+ self.class.send :define_method, "#{key}=" do |value|
36
+ self[key.to_sym] = value
37
+ end
38
+
39
+ super(key, value)
40
+ end
41
+
42
+ def method_missing(name, *args, &block)
43
+ if name.to_s.end_with?('=') && args.size == 1
44
+ key = name.to_s[0...-1]
45
+ self[key.to_sym] = args[0]
46
+ else
47
+ super
48
+ end
49
+ end
50
+
51
+ def _geometry_features(the_geom)
52
+
53
+ begin
54
+ the_geom = RGeo::WKRep::WKBParser.new(RGeo::Geographic.spherical_factory(:srid => 4326), :support_ewkb => true).parse(the_geom)
55
+ rescue
56
+ begin
57
+ the_geom = RGeo::GeoJSON.decode(the_geom, :json_parser => :json, :geo_factory => RGeo::Geographic.spherical_factory(:srid => 4326))
58
+ rescue
59
+ end
60
+ end
61
+
62
+ case the_geom
63
+ when RGeo::Feature::Point || RGeo::Geographic::SphericalPointImpl
64
+ self.class.send :define_method, :latitude do
65
+ self.the_geom ? self.the_geom.y : nil
66
+ end
67
+
68
+ self.class.send :define_method, :longitude do
69
+ self.the_geom ? self.the_geom.x : nil
70
+ end
71
+ end
72
+
73
+ the_geom
74
+ end
75
+ private :_geometry_features
76
+
77
+ def cast_value(value)
78
+ return nil if value.nil?
79
+ return true if value.eql?('t')
80
+ return false if value.eql?('f')
81
+
82
+ begin
83
+ value = Float(value)
84
+ return value == value.floor ? value.to_i : value
85
+ rescue
86
+ end
87
+
88
+ return DateTime.strptime(value, '%Y-%m-%d') rescue
89
+ return DateTime.strptime(value, '%d-%m-%Y') rescue
90
+
91
+ value
92
+ end
93
+ private :cast_value
94
+
95
+ end
96
+ end
97
+ 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,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.4.3"
5
+ end
6
+ end
7
+ end
@@ -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,357 @@
1
+ # coding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ describe 'CartoDB client', :vcr => true 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
+
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
140
+
141
+ it "should add and remove colums in a previously created table" do
142
+ CartoDB::Connection.create_table 'cartodb_spec'
143
+ CartoDB::Connection.add_column 'cartodb_spec', 'field1', 'text'
144
+ CartoDB::Connection.add_column 'cartodb_spec', 'field2', 'numeric'
145
+ CartoDB::Connection.add_column 'cartodb_spec', 'field3', 'date'
146
+
147
+ table = CartoDB::Connection.table 'cartodb_spec'
148
+ table.schema.should have(9).items
149
+ table.schema.should include(["field1", "string"])
150
+ table.schema.should include(["field2", "number"])
151
+ table.schema.should include(["field3", "date"])
152
+
153
+ CartoDB::Connection.drop_column 'cartodb_spec', 'field3'
154
+ table = CartoDB::Connection.table 'cartodb_spec'
155
+ table.schema.should have(8).items
156
+ table.schema.should_not include(["field3", "date"])
157
+ end
158
+
159
+ it "should change a previously created column" do
160
+ CartoDB::Connection.create_table 'cartodb_spec', [{:name => 'field1', :type => 'text'}]
161
+ CartoDB::Connection.change_column 'cartodb_spec', "field1", "changed_field", "numeric"
162
+ table = CartoDB::Connection.table 'cartodb_spec'
163
+ table.schema.should_not include(["field1", "string"])
164
+ table.schema.should include(["changed_field", "number"])
165
+ end
166
+
167
+ it "should return user's table list" do
168
+ table_1 = CartoDB::Connection.create_table 'table #1'
169
+ table_2 = CartoDB::Connection.create_table 'table #2'
170
+
171
+ tables_list = CartoDB::Connection.tables
172
+ tables_list.tables.should have(2).items
173
+ tables_list.tables.map(&:name).should include(table_1.name)
174
+ tables_list.tables.map(&:name).should include(table_2.name)
175
+ end
176
+
177
+ it "should drop a table" do
178
+ table_1 = CartoDB::Connection.create_table 'table #1'
179
+ table_2 = CartoDB::Connection.create_table 'table #2'
180
+ table_3 = CartoDB::Connection.create_table 'table #3'
181
+
182
+ CartoDB::Connection.drop_table 'table_2'
183
+
184
+ tables_list = CartoDB::Connection.tables
185
+ tables_list.tables.should have(2).items
186
+ tables_list.tables.map(&:name).should include(table_1.name)
187
+ tables_list.tables.map(&:name).should include(table_3.name)
188
+ end
189
+
190
+ it "should insert a row in a table" do
191
+ table = CartoDB::Connection.create_table 'table #1', [
192
+ {:name => 'field1', :type => 'text'},
193
+ {:name => 'field2', :type => 'numeric'},
194
+ {:name => 'field3', :type => 'date'},
195
+ {:name => 'field4', :type => 'boolean'}
196
+ ]
197
+
198
+ today = DateTime.new(2004, 1, 1)
199
+
200
+ record = CartoDB::Connection.insert_row 'table_1', {
201
+ 'field1' => 'lorem',
202
+ 'field2' => 100.99,
203
+ 'field3' => today,
204
+ 'field4' => true
205
+ }
206
+
207
+ record.field1.should == 'lorem'
208
+ record.field2.should == 100.99
209
+ record.field3.to_date.should == today.to_date
210
+ record.field4.should == true
211
+ end
212
+
213
+ it "should update a row in a table" do
214
+ table = CartoDB::Connection.create_table 'table #1', [
215
+ {:name => 'field1', :type => 'text'},
216
+ {:name => 'field2', :type => 'numeric'},
217
+ {:name => 'field3', :type => 'date'},
218
+ {:name => 'field4', :type => 'boolean'}
219
+ ]
220
+
221
+ today = DateTime.new(2004, 1, 1)
222
+
223
+ record = CartoDB::Connection.insert_row 'table_1', {
224
+ 'field1' => 'lorem',
225
+ 'field2' => 100.99,
226
+ 'field3' => today,
227
+ 'field4' => true
228
+ }
229
+
230
+ record = CartoDB::Connection.update_row 'table_1', record.id, {
231
+ 'field1' => 'illum',
232
+ 'field2' => -83.24,
233
+ 'field3' => today + 1,
234
+ 'field4' => false
235
+ }
236
+
237
+ record.field1.should == 'illum'
238
+ record.field2.should == -83.24
239
+ record.field3.to_date.should == (today + 1).to_date
240
+ record.field4.should == false
241
+ end
242
+
243
+ it "should delete a table's row" do
244
+ table = CartoDB::Connection.create_table 'table #1', [
245
+ {:name => 'field1', :type => 'text'},
246
+ {:name => 'field2', :type => 'numeric'},
247
+ {:name => 'field3', :type => 'date'},
248
+ {:name => 'field4', :type => 'boolean'}
249
+ ]
250
+
251
+ today = Time.now
252
+
253
+ record = CartoDB::Connection.insert_row 'table_1', {
254
+ 'field1' => 'lorem',
255
+ 'field2' => 100.99,
256
+ 'field3' => today,
257
+ 'field4' => true
258
+ }
259
+
260
+ CartoDB::Connection.delete_row 'table_1', record.id
261
+
262
+ records = CartoDB::Connection.records 'table_1'
263
+
264
+ records.name.should be == 'table_1'
265
+ records.total_rows.should == 0
266
+ records.rows.should be_empty
267
+ end
268
+
269
+ it "should execute a select query and return results" do
270
+ table = CartoDB::Connection.create_table 'table #1'
271
+
272
+ 10.times do
273
+ row = CartoDB::Connection.insert_row 'table_1', {
274
+ 'name' => String.random(15),
275
+ 'description' => String.random(200),
276
+ 'the_geom' => RgeoFactory.point(-3.69962, 40.42222)
277
+ }
278
+
279
+ end
280
+ results = CartoDB::Connection.query("SELECT * FROM table_1")
281
+ results.should_not be_nil
282
+ results.time.should be > 0
283
+ results.total_rows.should == 10
284
+ results.rows.should have(10).items
285
+ results.rows.each do |row|
286
+ row.cartodb_id.should be > 0
287
+ row.name.should_not be_empty
288
+ row.latitude.should be == 40.42222
289
+ row.longitude.should be == -3.69962
290
+ row.description.should_not be_empty
291
+ row.created_at.should_not be_nil
292
+ row.updated_at.should_not be_nil
293
+ end
294
+ end
295
+
296
+ it "should get a table by its name" do
297
+ created_table = CartoDB::Connection.create_table 'table_with_name'
298
+
299
+ table = CartoDB::Connection.table 'table_with_name'
300
+ table.should_not be_nil
301
+ table.name.should be == created_table.name
302
+ end
303
+
304
+ it "should return nil when requesting a table which does not exists" do
305
+ expect{CartoDB::Connection.table('non_existing_table')}.to raise_error(CartoDB::Client::Error)
306
+ end
307
+
308
+ it "should return errors on invalid queries" do
309
+ expect{results = CartoDB::Connection.query("SELECT 1 FROM non_existing_table")}.to raise_error(CartoDB::Client::Error, /relation "non_existing_table" does not exist/)
310
+ end
311
+
312
+ it "should paginate records" do
313
+ table = CartoDB::Connection.create_table 'table #1'
314
+
315
+ 50.times do
316
+ CartoDB::Connection.insert_row 'table_1', {
317
+ 'name' => String.random(15),
318
+ 'description' => String.random(200),
319
+ 'the_geom' => RgeoFactory.point(rand(180), rand(90))
320
+ }
321
+ end
322
+
323
+ records = CartoDB::Connection.records 'table_1', :page => 0, :rows_per_page => 20
324
+ records.total_rows.should be == 50
325
+ records.rows.should have(20).records
326
+ records.rows.first.cartodb_id.should be == 1
327
+ records.rows.last.cartodb_id.should be == 20
328
+
329
+ records = CartoDB::Connection.records 'table_1', :page => 1, :rows_per_page => 20
330
+ records.total_rows.should be == 50
331
+ records.rows.should have(20).records
332
+ records.rows.first.cartodb_id.should be == 21
333
+ records.rows.last.cartodb_id.should be == 40
334
+
335
+ end
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
+
357
+ end