cartodb-rb-client-rails-322 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +5 -0
- data/.rvmrc +1 -0
- data/.travis.yml +15 -0
- data/Gemfile +15 -0
- data/LICENSE +28 -0
- data/README.markdown +365 -0
- data/Rakefile +10 -0
- data/cartodb-rb-client.gemspec +34 -0
- data/lib/cartodb-rb-client.rb +18 -0
- data/lib/cartodb-rb-client/cartodb.rb +6 -0
- data/lib/cartodb-rb-client/cartodb/client.rb +4 -0
- data/lib/cartodb-rb-client/cartodb/client/authorization.rb +92 -0
- data/lib/cartodb-rb-client/cartodb/client/cache.rb +14 -0
- data/lib/cartodb-rb-client/cartodb/client/connection.rb +4 -0
- data/lib/cartodb-rb-client/cartodb/client/connection/base.rb +44 -0
- data/lib/cartodb-rb-client/cartodb/client/connection/cartodb.rb +280 -0
- data/lib/cartodb-rb-client/cartodb/client/connection/postgres.rb +255 -0
- data/lib/cartodb-rb-client/cartodb/client/error.rb +68 -0
- data/lib/cartodb-rb-client/cartodb/client/utils.rb +20 -0
- data/lib/cartodb-rb-client/cartodb/helpers.rb +1 -0
- data/lib/cartodb-rb-client/cartodb/helpers/sql_helper.rb +36 -0
- data/lib/cartodb-rb-client/cartodb/init.rb +30 -0
- data/lib/cartodb-rb-client/cartodb/libs.rb +2 -0
- data/lib/cartodb-rb-client/cartodb/libs/object.rb +15 -0
- data/lib/cartodb-rb-client/cartodb/libs/string.rb +116 -0
- data/lib/cartodb-rb-client/cartodb/model.rb +11 -0
- data/lib/cartodb-rb-client/cartodb/model/base.rb +20 -0
- data/lib/cartodb-rb-client/cartodb/model/constants.rb +30 -0
- data/lib/cartodb-rb-client/cartodb/model/defaults.rb +15 -0
- data/lib/cartodb-rb-client/cartodb/model/geo.rb +101 -0
- data/lib/cartodb-rb-client/cartodb/model/getters.rb +75 -0
- data/lib/cartodb-rb-client/cartodb/model/persistence.rb +69 -0
- data/lib/cartodb-rb-client/cartodb/model/query.rb +66 -0
- data/lib/cartodb-rb-client/cartodb/model/schema.rb +121 -0
- data/lib/cartodb-rb-client/cartodb/model/scope.rb +163 -0
- data/lib/cartodb-rb-client/cartodb/model/setters.rb +37 -0
- data/lib/cartodb-rb-client/cartodb/types.rb +2 -0
- data/lib/cartodb-rb-client/cartodb/types/metadata.rb +97 -0
- data/lib/cartodb-rb-client/cartodb/types/pg_result.rb +17 -0
- data/lib/cartodb-rb-client/install_utils.rb +19 -0
- data/lib/cartodb-rb-client/version.rb +7 -0
- data/run_tests.sh +6 -0
- data/spec/client_spec.rb +357 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_add_and_remove_colums_in_a_previously_created_table.yml +635 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_allow_reserved_words_in_columns_names.yml +284 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_change_a_previously_created_column.yml +362 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_create_a_table_and_get_its_table_definition.yml +1634 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_create_a_table_forcing_the_schema_and_get_its_table_definition.yml +298 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_create_a_table_from_a_csv_file.yml +2947 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_create_a_table_with_MULTILINESTRING_type_geometry.yml +299 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_create_a_table_with_MULTIPOLYGON_type_geometry.yml +298 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_create_a_table_with_POINT_type_geometry.yml +580 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_delete_a_table_s_row.yml +410 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_drop_a_table.yml +380 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_escape_properly_input_data_in_insert_queries.yml +295 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_execute_a_select_query_and_return_results.yml +987 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_get_a_table_by_its_name.yml +298 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_import_any_kind_of_data_file.yml +6951 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_insert_a_row_in_a_table.yml +357 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_paginate_records.yml +3642 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_rename_an_existing_table.yml +299 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_return_errors_on_invalid_queries.yml +132 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_return_nil_when_requesting_a_table_which_does_not_exists.yml +218 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_return_user_s_table_list.yml +244 -0
- data/spec/fixtures/cassettes/CartoDB_client/should_update_a_row_in_a_table.yml +347 -0
- data/spec/fixtures/cassettes/CartoDB_model_data_methods/should_destroy_a_previously_created_record.yml +1920 -0
- data/spec/fixtures/cassettes/CartoDB_model_data_methods/should_initialize_attributes_of_the_model_without_persisting_them.yml +963 -0
- data/spec/fixtures/cassettes/CartoDB_model_data_methods/should_persist_into_cartodb_using_the_save_method.yml +1946 -0
- data/spec/fixtures/cassettes/CartoDB_model_data_methods/should_persist_into_cartodb_using_the_static_create_method.yml +1796 -0
- data/spec/fixtures/cassettes/CartoDB_model_data_methods/should_save_polygons_in_different_formats.yml +1801 -0
- data/spec/fixtures/cassettes/CartoDB_model_data_methods/should_update_an_existing_record.yml +2856 -0
- data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_add_more_columns_if_the_table_previously_exists.yml +1509 -0
- data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_contain_an_array_of_columns.yml +2007 -0
- data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_create_a_table_with_custom_name_if_specified.yml +357 -0
- data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_create_model_with_custom_data_types_columns.yml +565 -0
- data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_create_model_with_polygon_type_geometry_columns.yml +493 -0
- data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_create_the_table_in_cartodb_if_it_doesn_t_exists.yml +1048 -0
- data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_have_a_valid_CartoDB_Client_instance_as_a_connection_object.yml +971 -0
- data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_have_a_valid_table_name.yml +970 -0
- data/spec/fixtures/cassettes/CartoDB_model_metadata_methods/should_return_only_data_columns.yml +1096 -0
- data/spec/fixtures/cassettes/CartoDB_model_scopes/should_allow_to_select_the_specified_fiels.yml +25828 -0
- data/spec/fixtures/cassettes/CartoDB_model_scopes/should_count_all_records.yml +22401 -0
- data/spec/fixtures/cassettes/CartoDB_model_scopes/should_find_a_record_by_its_id.yml +21852 -0
- data/spec/fixtures/cassettes/CartoDB_model_scopes/should_order_results.yml +23701 -0
- data/spec/fixtures/cassettes/CartoDB_model_scopes/should_paginate_results.yml +35644 -0
- data/spec/fixtures/cassettes/CartoDB_model_scopes/should_return_all_records_paginated.yml +23699 -0
- data/spec/fixtures/cassettes/CartoDB_model_scopes/should_search_records_by_certain_filters.yml +7080 -0
- data/spec/fixtures/cassettes/cartodb_spec_models.yml +3409 -0
- data/spec/fixtures/cassettes/clean_tables.yml +224 -0
- data/spec/model/data_spec.rb +157 -0
- data/spec/model/metadata_spec.rb +124 -0
- data/spec/model/scopes_spec.rb +171 -0
- data/spec/model_specs_helper.rb +2 -0
- data/spec/spec_helper.rb +54 -0
- data/spec/support/cartodb_config.yml +11 -0
- data/spec/support/cartodb_config.yml.sample +16 -0
- data/spec/support/cartodb_factories.rb +33 -0
- data/spec/support/cartodb_helpers.rb +14 -0
- data/spec/support/cartodb_models.rb +29 -0
- data/spec/support/data/110m-glaciated-areas.zip +0 -0
- data/spec/support/data/CartoDB_csv_export.zip +0 -0
- data/spec/support/data/CartoDB_shp_export.zip +0 -0
- data/spec/support/data/rmnp.kml +51 -0
- data/spec/support/data/states.kml.zip +0 -0
- data/spec/support/database.yml +5 -0
- data/spec/support/shp/cereal.dbf +0 -0
- data/spec/support/shp/cereal.shp +0 -0
- data/spec/support/shp/cereal.shx +0 -0
- data/spec/support/shp/cereal.zip +0 -0
- data/spec/support/shp/parcelas.dbf +0 -0
- data/spec/support/shp/parcelas.shp +0 -0
- data/spec/support/shp/parcelas.shx +0 -0
- data/spec/support/shp/parcelas.zip +0 -0
- data/spec/support/shp/zonas.dbf +0 -0
- data/spec/support/shp/zonas.shp +0 -0
- data/spec/support/shp/zonas.shx +0 -0
- data/spec/support/shp/zonas.zip +0 -0
- data/spec/support/whs_features.csv +315 -0
- data/spec/support/whs_features.csv.zip +0 -0
- data/spec/support/whs_features_temp.csv +315 -0
- 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,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,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
|
data/run_tests.sh
ADDED
data/spec/client_spec.rb
ADDED
@@ -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
|