redshift-on-postgres-adapter 0.1.1 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cc4ea52a6cec6775aac84c1711973c1624594f84
4
- data.tar.gz: 4911ef9d2c209fb0ce3520673519e818b785df8c
3
+ metadata.gz: 62e429688c40157d24f90a268531368e97c4c85b
4
+ data.tar.gz: b3841ac0057bb23434b7adc2b2c2cec2b8c12ccd
5
5
  SHA512:
6
- metadata.gz: a852e81f0e07a13c204ed00aa3a944386bc74581c60c432a6bf46ca86afe828b7f8558461ee62b8499bdb4127d2619c013573b5953b93540c32483530bc7b6df
7
- data.tar.gz: 3d0a950f4639ae94fe999e203658d0e099f1c3a340e001a99951c6a32d76a092ea977ab0ec0a9b9faceb010cfeae52f0c0a085521300e10492ad692c42d3c5be
6
+ metadata.gz: d8ae23dbbcf94eab0a76684335c11a653662da627b9ace8fc3ce2d0de566417f513ef91a574e6dfad26c839f491642b66d63fc86f7cac6aff583398e5f811584
7
+ data.tar.gz: 52d8afbdc7816fdec9a1dc4ebaa6dcd7db789dee51c970251a220dc49002e9e6bae4bc8ced4590bff3ec2663b403316d0673c5fee273ceab1498d6cdb897010a
@@ -0,0 +1,28 @@
1
+
2
+ module ActiveRecord::ConnectionAdapters
3
+ module Redshift
4
+
5
+ class ColumnDefinition < PostgreSQL::ColumnDefinition
6
+ attr_accessor :distkey, :sortkey, :encode
7
+ end
8
+
9
+ class TableDefinition < PostgreSQL::TableDefinition
10
+ def new_column_definition(name, type, options) # :nodoc:
11
+ column = super
12
+ column.distkey = options[:distkey]
13
+ column.sortkey = options[:sortkey]
14
+ column.encode = options[:encode]
15
+ column
16
+ end
17
+
18
+ private
19
+
20
+ def create_column_definition(name, type)
21
+ ColumnDefinition.new(name, type)
22
+ end
23
+ end
24
+
25
+ class Table < PostgreSQL::Table
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,44 @@
1
+
2
+ module ActiveRecord::ConnectionAdapters
3
+ module Redshift
4
+ class SchemaCreation < PostgreSQL::SchemaCreation
5
+ ENCODING_TYPES = %w[RAW BYTEDICT DELTA DELTA32K LZO MOSTLY8 MOSTLY16 MOSTLY32 RUNLENGTH TEXT255 TEXT32K]
6
+
7
+ def column_options(o)
8
+ column_options = super
9
+ column_options[:distkey] = o.distkey
10
+ column_options[:sortkey] = o.sortkey
11
+
12
+ if o.encode
13
+ encode = o.encode.to_s.upcase
14
+ if ENCODING_TYPES.include?(encode)
15
+ column_options[:encode] = encode
16
+ else
17
+ raise "Invalid encoding type: #{o.encode}"
18
+ end
19
+ else
20
+ # column_options[:encode] = 'RAW'
21
+ end
22
+
23
+ column_options
24
+ end
25
+
26
+ # Support
27
+ def add_column_options!(sql, options)
28
+ if options[:distkey]
29
+ sql << ' DISTKEY'
30
+ end
31
+
32
+ if options[:sortkey]
33
+ sql << ' SORTKEY'
34
+ end
35
+
36
+ if options[:encode]
37
+ sql << " ENCODE #{options[:encode]}"
38
+ end
39
+
40
+ super
41
+ end
42
+ end
43
+ end
44
+ end
@@ -2,6 +2,8 @@
2
2
  require 'active_record/connection_adapters/postgresql_adapter'
3
3
 
4
4
  require 'active_record/tasks/redshift_database_tasks'
5
+ require 'active_record/connection_adapters/redshift/schema_statements'
6
+ require 'active_record/connection_adapters/redshift/schema_definitions'
5
7
 
6
8
  ActiveRecord::Tasks::DatabaseTasks.register_task(/redshift/, ActiveRecord::Tasks::RedshiftDatabaseTasks)
7
9
 
@@ -24,143 +26,167 @@ module ActiveRecord::ConnectionHandling
24
26
  end
25
27
  end
26
28
 
27
- class ActiveRecord::ConnectionAdapters::RedshiftAdapter < ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
28
- ADAPTER_NAME = 'Redshift'.freeze
29
+ module ActiveRecord::ConnectionAdapters
30
+ class RedshiftAdapter < PostgreSQLAdapter
31
+ ADAPTER_NAME = 'Redshift'.freeze
29
32
 
30
- def initialize(connection, logger, connection_parameters, config)
31
- super
32
- end
33
+ NATIVE_DATABASE_TYPES = PostgreSQLAdapter::NATIVE_DATABASE_TYPES.merge({
34
+ primary_key: "bigint primary key identity(1,1)",
35
+ })
36
+
37
+ def initialize(connection, logger, connection_parameters, config)
38
+ super
39
+ end
33
40
 
34
- # Configures the encoding, verbosity, schema search path, and time zone of the connection.
35
- # This is called by #connect and should not be called manually.
36
- def configure_connection
37
- if @config[:encoding]
38
- @connection.set_client_encoding(@config[:encoding])
39
- end
40
- # self.client_min_messages = @config[:min_messages] || 'warning'
41
- self.schema_search_path = @config[:schema_search_path] || @config[:schema_order]
42
-
43
- # Use standard-conforming strings so we don't have to do the E'...' dance.
44
- # set_standard_conforming_strings
45
-
46
- # If using Active Record's time zone support configure the connection to return
47
- # TIMESTAMP WITH ZONE types in UTC.
48
- # (SET TIME ZONE does not use an equals sign like other SET variables)
49
- # if ActiveRecord::Base.default_timezone == :utc
50
- # execute("SET time zone 'UTC'", 'SCHEMA')
51
- # elsif @local_tz
52
- # execute("SET time zone '#{@local_tz}'", 'SCHEMA')
53
- # end
54
-
55
- # SET statements from :variables config hash
56
- # http://www.postgresql.org/docs/8.3/static/sql-set.html
57
- variables = @config[:variables] || {}
58
- variables.map do |k, v|
59
- if v == ':default' || v == :default
60
- # Sets the value to the global or compile default
61
- execute("SET SESSION #{k} TO DEFAULT", 'SCHEMA')
62
- elsif !v.nil?
63
- execute("SET SESSION #{k} TO #{quote(v)}", 'SCHEMA')
41
+ # Configures the encoding, verbosity, schema search path, and time zone of the connection.
42
+ # This is called by #connect and should not be called manually.
43
+ def configure_connection
44
+ if @config[:encoding]
45
+ @connection.set_client_encoding(@config[:encoding])
46
+ end
47
+ # self.client_min_messages = @config[:min_messages] || 'warning'
48
+ self.schema_search_path = @config[:schema_search_path] || @config[:schema_order]
49
+
50
+ # Use standard-conforming strings so we don't have to do the E'...' dance.
51
+ # set_standard_conforming_strings
52
+
53
+ # If using Active Record's time zone support configure the connection to return
54
+ # TIMESTAMP WITH ZONE types in UTC.
55
+ # (SET TIME ZONE does not use an equals sign like other SET variables)
56
+ # if ActiveRecord::Base.default_timezone == :utc
57
+ # execute("SET time zone 'UTC'", 'SCHEMA')
58
+ # elsif @local_tz
59
+ # execute("SET time zone '#{@local_tz}'", 'SCHEMA')
60
+ # end
61
+
62
+ # SET statements from :variables config hash
63
+ # http://www.postgresql.org/docs/8.3/static/sql-set.html
64
+ variables = @config[:variables] || {}
65
+ variables.map do |k, v|
66
+ if v == ':default' || v == :default
67
+ # Sets the value to the global or compile default
68
+ execute("SET SESSION #{k} TO DEFAULT", 'SCHEMA')
69
+ elsif !v.nil?
70
+ execute("SET SESSION #{k} TO #{quote(v)}", 'SCHEMA')
71
+ end
64
72
  end
65
73
  end
66
- end
67
74
 
68
- def postgresql_version
69
- return 100000 + 80002
70
- end
75
+ def postgresql_version
76
+ # Hack to avoid native PostgreQLAdapter's version check
77
+ return 100000 + 80002
78
+ end
71
79
 
72
- def supports_statement_cache?
73
- false
74
- end
80
+ def native_database_types #:nodoc:
81
+ NATIVE_DATABASE_TYPES
82
+ end
75
83
 
76
- def supports_index_sort_order?
77
- false
78
- end
84
+ def supports_statement_cache?
85
+ false
86
+ end
79
87
 
80
- def supports_partial_index?
81
- false
82
- end
88
+ def supports_index_sort_order?
89
+ false
90
+ end
83
91
 
84
- def supports_transaction_isolation?
85
- false
86
- end
92
+ def supports_partial_index?
93
+ false
94
+ end
87
95
 
88
- def supports_foreign_keys?
89
- false
90
- end
96
+ def supports_transaction_isolation?
97
+ false
98
+ end
91
99
 
92
- def supports_views?
93
- false
94
- end
100
+ def supports_foreign_keys?
101
+ false
102
+ end
95
103
 
96
- def supports_extensions?
97
- false
98
- end
104
+ def supports_views?
105
+ false
106
+ end
99
107
 
100
- def supports_ranges?
101
- false
102
- end
108
+ def supports_extensions?
109
+ false
110
+ end
103
111
 
104
- def supports_materialized_views?
105
- false
106
- end
112
+ def supports_ranges?
113
+ false
114
+ end
107
115
 
108
- def use_insert_returning?
109
- false
110
- end
116
+ def supports_materialized_views?
117
+ false
118
+ end
111
119
 
112
- # Returns the list of a table's column names, data types, and default values.
113
- #
114
- # The underlying query is roughly:
115
- # SELECT column.name, column.type, default.value
116
- # FROM column LEFT JOIN default
117
- # ON column.table_id = default.table_id
118
- # AND column.num = default.column_num
119
- # WHERE column.table_id = get_table_id('table_name')
120
- # AND column.num > 0
121
- # AND NOT column.is_dropped
122
- # ORDER BY column.num
123
- #
124
- # If the table name is not prefixed with a schema, the database will
125
- # take the first match from the schema search path.
126
- #
127
- # Query implementation notes:
128
- # - format_type includes the column size constraint, e.g. varchar(50)
129
- # - ::regclass is a function that gives the id for a table name
130
- def column_definitions(table_name) #:nodoc:
131
- exec_query(<<-end_sql, 'SCHEMA').rows
132
- SELECT a.attname, format_type(a.atttypid, a.atttypmod),
133
- pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
134
- FROM pg_attribute a LEFT JOIN pg_attrdef d
135
- ON a.attrelid = d.adrelid AND a.attnum = d.adnum
136
- WHERE a.attrelid = '#{quote_table_name(table_name)}'::regclass
137
- AND a.attnum > 0 AND NOT a.attisdropped
138
- ORDER BY a.attnum
139
- end_sql
140
- end
120
+ def use_insert_returning?
121
+ false
122
+ end
141
123
 
142
- # Returns just a table's primary key
143
- def primary_keys(table)
144
- row = exec_query(<<-end_sql, 'SCHEMA').rows.map do |row|
145
- SELECT DISTINCT(attr.attname)
146
- FROM pg_attribute attr
147
- INNER JOIN pg_depend dep ON attr.attrelid = dep.refobjid AND attr.attnum = dep.refobjsubid
148
- INNER JOIN pg_constraint cons ON attr.attrelid = cons.conrelid AND attr.attnum = cons.conkey[1]
149
- WHERE cons.contype = 'p'
150
- AND dep.refobjid = '#{quote_table_name(table)}'::regclass
151
- end_sql
152
- row && row.first
124
+ # Returns the list of a table's column names, data types, and default values.
125
+ #
126
+ # The underlying query is roughly:
127
+ # SELECT column.name, column.type, default.value
128
+ # FROM column LEFT JOIN default
129
+ # ON column.table_id = default.table_id
130
+ # AND column.num = default.column_num
131
+ # WHERE column.table_id = get_table_id('table_name')
132
+ # AND column.num > 0
133
+ # AND NOT column.is_dropped
134
+ # ORDER BY column.num
135
+ #
136
+ # If the table name is not prefixed with a schema, the database will
137
+ # take the first match from the schema search path.
138
+ #
139
+ # Query implementation notes:
140
+ # - format_type includes the column size constraint, e.g. varchar(50)
141
+ # - ::regclass is a function that gives the id for a table name
142
+ def column_definitions(table_name) #:nodoc:
143
+ exec_query(<<-end_sql, 'SCHEMA').rows
144
+ SELECT a.attname, format_type(a.atttypid, a.atttypmod),
145
+ pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
146
+ FROM pg_attribute a LEFT JOIN pg_attrdef d
147
+ ON a.attrelid = d.adrelid AND a.attnum = d.adnum
148
+ WHERE a.attrelid = '#{quote_table_name(table_name)}'::regclass
149
+ AND a.attnum > 0 AND NOT a.attisdropped
150
+ ORDER BY a.attnum
151
+ end_sql
153
152
  end
154
- end
155
153
 
156
- def indexes(table_name, name = nil)
157
- []
158
- end
154
+ # Returns just a table's primary key
155
+ def primary_keys(table)
156
+ row = exec_query(<<-end_sql, 'SCHEMA').rows.map do |row|
157
+ SELECT DISTINCT(attr.attname)
158
+ FROM pg_attribute attr
159
+ INNER JOIN pg_depend dep ON attr.attrelid = dep.refobjid AND attr.attnum = dep.refobjsubid
160
+ INNER JOIN pg_constraint cons ON attr.attrelid = cons.conrelid AND attr.attnum = cons.conkey[1]
161
+ WHERE cons.contype = 'p'
162
+ AND dep.refobjid = '#{quote_table_name(table)}'::regclass
163
+ end_sql
164
+ row && row.first
165
+ end
166
+ end
159
167
 
160
- def get_advisory_lock(lock_id)
161
- lock_id
162
- end
168
+ def indexes(table_name, name = nil)
169
+ []
170
+ end
171
+
172
+ def get_advisory_lock(lock_id)
173
+ lock_id
174
+ end
175
+
176
+ def release_advisory_lock(lock_id)
177
+ end
163
178
 
164
- def release_advisory_lock(lock_id)
179
+ # Schema Statements
180
+ def create_table_definition(*args) # :nodoc:
181
+ Redshift::TableDefinition.new(*args)
182
+ end
183
+
184
+ def update_table_definition(table_name, base) #:nodoc:
185
+ Redshift::Table.new(table_name, base)
186
+ end
187
+
188
+ def schema_creation # :nodoc:
189
+ Redshift::SchemaCreation.new self
190
+ end
165
191
  end
166
192
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redshift-on-postgres-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dongyi Liao
@@ -44,9 +44,10 @@ executables: []
44
44
  extensions: []
45
45
  extra_rdoc_files: []
46
46
  files:
47
+ - lib/active_record/connection_adapters/redshift/schema_definitions.rb
48
+ - lib/active_record/connection_adapters/redshift/schema_statements.rb
47
49
  - lib/active_record/connection_adapters/redshift_adapter.rb
48
- - lib/active_record/tasks/redshift_database_tasks.rb
49
- homepage: http://github.com/liaody
50
+ homepage: https://github.com/liaody/redshift-on-postgres-adapter
50
51
  licenses:
51
52
  - New BSD License
52
53
  metadata: {}
@@ -1,7 +0,0 @@
1
- require 'active_record/tasks/postgresql_database_tasks'
2
-
3
- class ActiveRecord::Tasks::RedshiftDatabaseTasks < ActiveRecord::Tasks::PostgreSQLDatabaseTasks # :nodoc:
4
- def initialize(configuration)
5
- super
6
- end
7
- end