activerecord-redshift-adapter-ng 0.9.0 → 0.9.1
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.
- checksums.yaml +4 -4
- data/LICENSE +0 -33
- data/README.md +12 -16
- data/lib/active_record/connection_adapters/redshift/column.rb +11 -1
- data/lib/active_record/connection_adapters/redshift/oid.rb +15 -0
- data/lib/active_record/connection_adapters/redshift/oid/array.rb +96 -0
- data/lib/active_record/connection_adapters/redshift/oid/bit.rb +52 -0
- data/lib/active_record/connection_adapters/redshift/oid/bit_varying.rb +13 -0
- data/lib/active_record/connection_adapters/redshift/oid/bytea.rb +14 -0
- data/lib/active_record/connection_adapters/redshift/oid/cidr.rb +46 -0
- data/lib/active_record/connection_adapters/redshift/oid/date_time.rb +0 -9
- data/lib/active_record/connection_adapters/redshift/oid/enum.rb +17 -0
- data/lib/active_record/connection_adapters/redshift/oid/hstore.rb +59 -0
- data/lib/active_record/connection_adapters/redshift/oid/inet.rb +13 -0
- data/lib/active_record/connection_adapters/redshift/oid/json.rb +1 -1
- data/lib/active_record/connection_adapters/redshift/oid/money.rb +43 -0
- data/lib/active_record/connection_adapters/redshift/oid/point.rb +43 -0
- data/lib/active_record/connection_adapters/redshift/oid/range.rb +76 -0
- data/lib/active_record/connection_adapters/redshift/oid/specialized_string.rb +15 -0
- data/lib/active_record/connection_adapters/redshift/oid/type_map_initializer.rb +42 -20
- data/lib/active_record/connection_adapters/redshift/oid/uuid.rb +28 -0
- data/lib/active_record/connection_adapters/redshift/oid/vector.rb +26 -0
- data/lib/active_record/connection_adapters/redshift/oid/xml.rb +28 -0
- data/lib/active_record/connection_adapters/redshift/quoting.rb +10 -0
- data/lib/active_record/connection_adapters/redshift/referential_integrity.rb +15 -0
- data/lib/active_record/connection_adapters/redshift/schema_definitions.rb +85 -0
- data/lib/active_record/connection_adapters/redshift/schema_statements.rb +171 -8
- data/lib/active_record/connection_adapters/redshift/utils.rb +4 -15
- data/lib/active_record/connection_adapters/redshift_adapter.rb +119 -38
- metadata +26 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ffdccdc8440d8d53be78f296fd2c137eab0481e1
|
4
|
+
data.tar.gz: f8402a7779848906a456ed6be8ec81210224d164
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9cb7ba3125df8eb048c44e0425ff49397a9c23df14385952b390fff3759b83e54b928adb7e93d396247291fd1dbf1073678528303a733cf51453fe7fa930a91
|
7
|
+
data.tar.gz: 6c10e072ad442a23d4b3b4c2acf2f65450bd2060bab15ee8c8c568204b812885d7f77bb783c604d7fdd6d6bb09f876a33163b2e2450f8c2c92bac9243bb1052d
|
data/LICENSE
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
-----------------------------------------------------------------------------------
|
2
1
|
The MIT License (MIT)
|
3
2
|
|
4
3
|
Copyright (c) 2004-2013 David Heinemeier Hansson (original code author)
|
@@ -20,35 +19,3 @@ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
20
19
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
21
20
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
22
21
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
-
|
24
|
-
-----------------------------------------------------------------------------------
|
25
|
-
Copyright (c) 2010-2013, Fiksu, Inc.
|
26
|
-
All rights reserved.
|
27
|
-
|
28
|
-
Redistribution and use in source and binary forms, with or without
|
29
|
-
modification, are permitted provided that the following conditions are
|
30
|
-
met:
|
31
|
-
|
32
|
-
o Redistributions of source code must retain the above copyright
|
33
|
-
notice, this list of conditions and the following disclaimer.
|
34
|
-
|
35
|
-
o Redistributions in binary form must reproduce the above copyright
|
36
|
-
notice, this list of conditions and the following disclaimer in the
|
37
|
-
documentation and/or other materials provided with the
|
38
|
-
distribution.
|
39
|
-
|
40
|
-
o Fiksu, Inc. nor the names of its contributors may be used to
|
41
|
-
endorse or promote products derived from this software without
|
42
|
-
specific prior written permission.
|
43
|
-
|
44
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
45
|
-
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
46
|
-
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
47
|
-
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
48
|
-
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
49
|
-
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
50
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
51
|
-
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
52
|
-
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
53
|
-
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
54
|
-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
CHANGED
@@ -1,34 +1,30 @@
|
|
1
|
-
|
1
|
+
activerecord4-redshift-adapter
|
2
|
+
==============================
|
2
3
|
|
3
|
-
Amazon Redshift adapter for ActiveRecord.
|
4
|
-
|
5
|
-
|
4
|
+
Amazon Redshift adapter for ActiveRecord 4 (Rails 4).
|
5
|
+
Almost all code are copied from ActiveRecord 4.2.0 PostgreSQL
|
6
|
+
driver and modified for Redshift.
|
6
7
|
|
7
|
-
|
8
|
-
but it currently supports only ActiveRecord 3. Also, AR4 code is magnifically
|
9
|
-
different from AR3 code because of file separation, patching does not work well.
|
10
|
-
I want to use Rails 4 with Redshift NOW, so I wrote this driver.
|
11
|
-
If anybody write better Redshift driver which works with ActiveRecord 4,
|
12
|
-
I abandon this driver.
|
8
|
+
Forked and heavily modified from (https://github.com/aamine/activerecord4-redshift-adapter).
|
13
9
|
|
14
|
-
|
10
|
+
How to Use
|
15
11
|
-------------------
|
16
12
|
|
17
|
-
|
13
|
+
In Gemfile
|
18
14
|
```
|
19
|
-
gem '
|
15
|
+
gem 'activerecord4-redshift-adapter', github: 'khwangster/activerecord4-redshift-adapter'
|
20
16
|
```
|
21
17
|
|
22
18
|
In database.yml
|
23
19
|
```
|
24
20
|
development:
|
25
21
|
adapter: redshift
|
26
|
-
host: your_cluster_name.
|
27
|
-
port: 5439
|
22
|
+
host: your_cluster_name.ident.ap-east-1.redshift.amazonaws.com
|
28
23
|
database: dev
|
24
|
+
port: 5439
|
29
25
|
username: your_user
|
30
26
|
password: your_password
|
31
|
-
encoding:
|
27
|
+
encoding: utf-8
|
32
28
|
pool: 3
|
33
29
|
timeout: 5000
|
34
30
|
```
|
@@ -1,8 +1,18 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module ConnectionAdapters
|
3
|
+
# PostgreSQL-specific extensions to column definitions in a table.
|
3
4
|
class RedshiftColumn < Column #:nodoc:
|
5
|
+
attr_accessor :array
|
6
|
+
|
4
7
|
def initialize(name, default, cast_type, sql_type = nil, null = true, default_function = nil)
|
5
|
-
|
8
|
+
if sql_type =~ /\[\]$/
|
9
|
+
@array = true
|
10
|
+
super(name, default, cast_type, sql_type[0..sql_type.length - 3], null)
|
11
|
+
else
|
12
|
+
@array = false
|
13
|
+
super(name, default, cast_type, sql_type, null)
|
14
|
+
end
|
15
|
+
|
6
16
|
@default_function = default_function
|
7
17
|
end
|
8
18
|
end
|
@@ -1,13 +1,28 @@
|
|
1
1
|
require 'active_record/connection_adapters/redshift/oid/infinity'
|
2
2
|
|
3
|
+
require 'active_record/connection_adapters/redshift/oid/array'
|
4
|
+
require 'active_record/connection_adapters/redshift/oid/bit'
|
5
|
+
require 'active_record/connection_adapters/redshift/oid/bit_varying'
|
6
|
+
require 'active_record/connection_adapters/redshift/oid/bytea'
|
7
|
+
require 'active_record/connection_adapters/redshift/oid/cidr'
|
3
8
|
require 'active_record/connection_adapters/redshift/oid/date'
|
4
9
|
require 'active_record/connection_adapters/redshift/oid/date_time'
|
5
10
|
require 'active_record/connection_adapters/redshift/oid/decimal'
|
11
|
+
require 'active_record/connection_adapters/redshift/oid/enum'
|
6
12
|
require 'active_record/connection_adapters/redshift/oid/float'
|
13
|
+
require 'active_record/connection_adapters/redshift/oid/hstore'
|
14
|
+
require 'active_record/connection_adapters/redshift/oid/inet'
|
7
15
|
require 'active_record/connection_adapters/redshift/oid/integer'
|
8
16
|
require 'active_record/connection_adapters/redshift/oid/json'
|
9
17
|
require 'active_record/connection_adapters/redshift/oid/jsonb'
|
18
|
+
require 'active_record/connection_adapters/redshift/oid/money'
|
19
|
+
require 'active_record/connection_adapters/redshift/oid/point'
|
20
|
+
require 'active_record/connection_adapters/redshift/oid/range'
|
21
|
+
require 'active_record/connection_adapters/redshift/oid/specialized_string'
|
10
22
|
require 'active_record/connection_adapters/redshift/oid/time'
|
23
|
+
require 'active_record/connection_adapters/redshift/oid/uuid'
|
24
|
+
require 'active_record/connection_adapters/redshift/oid/vector'
|
25
|
+
require 'active_record/connection_adapters/redshift/oid/xml'
|
11
26
|
|
12
27
|
require 'active_record/connection_adapters/redshift/oid/type_map_initializer'
|
13
28
|
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
module Redshift
|
4
|
+
module OID # :nodoc:
|
5
|
+
class Array < Type::Value # :nodoc:
|
6
|
+
include Type::Mutable
|
7
|
+
|
8
|
+
# Loads pg_array_parser if available. String parsing can be
|
9
|
+
# performed quicker by a native extension, which will not create
|
10
|
+
# a large amount of Ruby objects that will need to be garbage
|
11
|
+
# collected. pg_array_parser has a C and Java extension
|
12
|
+
begin
|
13
|
+
require 'pg_array_parser'
|
14
|
+
include PgArrayParser
|
15
|
+
rescue LoadError
|
16
|
+
require 'active_record/connection_adapters/redshift/array_parser'
|
17
|
+
include Redshift::ArrayParser
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :subtype, :delimiter
|
21
|
+
delegate :type, to: :subtype
|
22
|
+
|
23
|
+
def initialize(subtype, delimiter = ',')
|
24
|
+
@subtype = subtype
|
25
|
+
@delimiter = delimiter
|
26
|
+
end
|
27
|
+
|
28
|
+
def type_cast_from_database(value)
|
29
|
+
if value.is_a?(::String)
|
30
|
+
type_cast_array(parse_pg_array(value), :type_cast_from_database)
|
31
|
+
else
|
32
|
+
super
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def type_cast_from_user(value)
|
37
|
+
type_cast_array(value, :type_cast_from_user)
|
38
|
+
end
|
39
|
+
|
40
|
+
def type_cast_for_database(value)
|
41
|
+
if value.is_a?(::Array)
|
42
|
+
cast_value_for_database(value)
|
43
|
+
else
|
44
|
+
super
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def type_cast_array(value, method)
|
51
|
+
if value.is_a?(::Array)
|
52
|
+
value.map { |item| type_cast_array(item, method) }
|
53
|
+
else
|
54
|
+
@subtype.public_send(method, value)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def cast_value_for_database(value)
|
59
|
+
if value.is_a?(::Array)
|
60
|
+
casted_values = value.map { |item| cast_value_for_database(item) }
|
61
|
+
"{#{casted_values.join(delimiter)}}"
|
62
|
+
else
|
63
|
+
quote_and_escape(subtype.type_cast_for_database(value))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
ARRAY_ESCAPE = "\\" * 2 * 2 # escape the backslash twice for PG arrays
|
68
|
+
|
69
|
+
def quote_and_escape(value)
|
70
|
+
case value
|
71
|
+
when ::String
|
72
|
+
if string_requires_quoting?(value)
|
73
|
+
value = value.gsub(/\\/, ARRAY_ESCAPE)
|
74
|
+
value.gsub!(/"/,"\\\"")
|
75
|
+
%("#{value}")
|
76
|
+
else
|
77
|
+
value
|
78
|
+
end
|
79
|
+
when nil then "NULL"
|
80
|
+
else value
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# See http://www.postgresql.org/docs/9.2/static/arrays.html#ARRAYS-IO
|
85
|
+
# for a list of all cases in which strings will be quoted.
|
86
|
+
def string_requires_quoting?(string)
|
87
|
+
string.empty? ||
|
88
|
+
string == "NULL" ||
|
89
|
+
string =~ /[\{\}"\\\s]/ ||
|
90
|
+
string.include?(delimiter)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
module Redshift
|
4
|
+
module OID # :nodoc:
|
5
|
+
class Bit < Type::Value # :nodoc:
|
6
|
+
def type
|
7
|
+
:bit
|
8
|
+
end
|
9
|
+
|
10
|
+
def type_cast(value)
|
11
|
+
if ::String === value
|
12
|
+
case value
|
13
|
+
when /^0x/i
|
14
|
+
value[2..-1].hex.to_s(2) # Hexadecimal notation
|
15
|
+
else
|
16
|
+
value # Bit-string notation
|
17
|
+
end
|
18
|
+
else
|
19
|
+
value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def type_cast_for_database(value)
|
24
|
+
Data.new(super) if value
|
25
|
+
end
|
26
|
+
|
27
|
+
class Data
|
28
|
+
def initialize(value)
|
29
|
+
@value = value
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
value
|
34
|
+
end
|
35
|
+
|
36
|
+
def binary?
|
37
|
+
/\A[01]*\Z/ === value
|
38
|
+
end
|
39
|
+
|
40
|
+
def hex?
|
41
|
+
/\A[0-9A-F]*\Z/i === value
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
attr_reader :value
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
module Redshift
|
4
|
+
module OID # :nodoc:
|
5
|
+
class Bytea < Type::Binary # :nodoc:
|
6
|
+
def type_cast_from_database(value)
|
7
|
+
return if value.nil?
|
8
|
+
PGconn.unescape_bytea(super)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
module Redshift
|
4
|
+
module OID # :nodoc:
|
5
|
+
class Cidr < Type::Value # :nodoc:
|
6
|
+
def type
|
7
|
+
:cidr
|
8
|
+
end
|
9
|
+
|
10
|
+
def type_cast_for_schema(value)
|
11
|
+
subnet_mask = value.instance_variable_get(:@mask_addr)
|
12
|
+
|
13
|
+
# If the subnet mask is equal to /32, don't output it
|
14
|
+
if subnet_mask == (2**32 - 1)
|
15
|
+
"\"#{value.to_s}\""
|
16
|
+
else
|
17
|
+
"\"#{value.to_s}/#{subnet_mask.to_s(2).count('1')}\""
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def type_cast_for_database(value)
|
22
|
+
if IPAddr === value
|
23
|
+
"#{value.to_s}/#{value.instance_variable_get(:@mask_addr).to_s(2).count('1')}"
|
24
|
+
else
|
25
|
+
value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def cast_value(value)
|
30
|
+
if value.nil?
|
31
|
+
nil
|
32
|
+
elsif String === value
|
33
|
+
begin
|
34
|
+
IPAddr.new(value)
|
35
|
+
rescue ArgumentError
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
else
|
39
|
+
value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -5,15 +5,6 @@ module ActiveRecord
|
|
5
5
|
class DateTime < Type::DateTime # :nodoc:
|
6
6
|
include Infinity
|
7
7
|
|
8
|
-
def type_cast_for_database(value)
|
9
|
-
if has_precision? && value.acts_like?(:time) && value.year <= 0
|
10
|
-
bce_year = format("%04d", -value.year + 1)
|
11
|
-
super.sub(/^-?\d+/, bce_year) + " BC"
|
12
|
-
else
|
13
|
-
super
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
8
|
def cast_value(value)
|
18
9
|
if value.is_a?(::String)
|
19
10
|
case value
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
module Redshift
|
4
|
+
module OID # :nodoc:
|
5
|
+
class Hstore < Type::Value # :nodoc:
|
6
|
+
include Type::Mutable
|
7
|
+
|
8
|
+
def type
|
9
|
+
:hstore
|
10
|
+
end
|
11
|
+
|
12
|
+
def type_cast_from_database(value)
|
13
|
+
if value.is_a?(::String)
|
14
|
+
::Hash[value.scan(HstorePair).map { |k, v|
|
15
|
+
v = v.upcase == 'NULL' ? nil : v.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1')
|
16
|
+
k = k.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1')
|
17
|
+
[k, v]
|
18
|
+
}]
|
19
|
+
else
|
20
|
+
value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def type_cast_for_database(value)
|
25
|
+
if value.is_a?(::Hash)
|
26
|
+
value.map { |k, v| "#{escape_hstore(k)}=>#{escape_hstore(v)}" }.join(', ')
|
27
|
+
else
|
28
|
+
value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def accessor
|
33
|
+
ActiveRecord::Store::StringKeyedHashAccessor
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
HstorePair = begin
|
39
|
+
quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"/
|
40
|
+
unquoted_string = /(?:\\.|[^\s,])[^\s=,\\]*(?:\\.[^\s=,\\]*|=[^,>])*/
|
41
|
+
/(#{quoted_string}|#{unquoted_string})\s*=>\s*(#{quoted_string}|#{unquoted_string})/
|
42
|
+
end
|
43
|
+
|
44
|
+
def escape_hstore(value)
|
45
|
+
if value.nil?
|
46
|
+
'NULL'
|
47
|
+
else
|
48
|
+
if value == ""
|
49
|
+
'""'
|
50
|
+
else
|
51
|
+
'"%s"' % value.to_s.gsub(/(["\\])/, '\\\\\1')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|