Class: ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter

Inherits:
AbstractAdapter
  • Object
show all
Includes:
ActiveRecord::ConnectionAdapters::Sunstone::ColumnDumper, ActiveRecord::ConnectionAdapters::Sunstone::DatabaseStatements, ActiveRecord::ConnectionAdapters::Sunstone::Quoting, ActiveRecord::ConnectionAdapters::Sunstone::SchemaStatements
Defined in:
lib/active_record/connection_adapters/sunstone_adapter.rb

Overview

The SunstoneAPI adapter.

Options:

  • :host - Defaults to a Unix-domain socket in /tmp. On machines without Unix-domain sockets, the default is to connect to localhost.
  • :port - Defaults to 5432.
  • :username - The API key to connect with
  • :encoding - An optional client encoding that is used in a SET client_encoding TO call on the connection.

Constant Summary collapse

ADAPTER_NAME =
'Sunstone'.freeze
VALID_SUNSTONE_CONN_PARAMS =
[:url, :host, :port, :api_key, :use_ssl, :user_agent, :ca_cert]
NATIVE_DATABASE_TYPES =
{
  string:      { name: "string" },
  number:      { name: "number" },
  json:        { name: "json" },
  boolean:     { name: "boolean" }
}

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ActiveRecord::ConnectionAdapters::Sunstone::ColumnDumper

#prepare_column_options

Methods included from ActiveRecord::ConnectionAdapters::Sunstone::DatabaseStatements

#affected_rows, #cacheable_query, #cast_result, #delete, #exec_delete, #exec_insert, #last_inserted_id, #perform_query, #raw_execute, #returning_column_values, #sar_for_insert, #select_all, #to_sar, #to_sar_and_binds, #to_sql, #update, #write_query?

Methods included from ActiveRecord::ConnectionAdapters::Sunstone::SchemaStatements

#column_definitions, #column_name_for_operation, #columns, #columns_for_distinct, #definition, #distinct_relation_for_primary_key, #fetch_type_metadata, #limit_definition, #lookup_cast_type, #new_column, #primary_key, #table_exists?, #tables, #views

Constructor Details

#initializeSunstoneAPIAdapter

Initializes and connects a SunstoneAPI adapter.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 70

def initialize(...)
  super

  conn_params = @config.compact
  if conn_params[:url]
    uri = URI.parse(conn_params.delete(:url))
    conn_params[:api_key] ||= (uri.user ? CGI.unescape(uri.user) : nil)
    conn_params[:host]    ||= uri.host
    conn_params[:port]    ||= uri.port
    conn_params[:use_ssl] ||= (uri.scheme == 'https')
  end

  # Forward only valid config params to Sunstone::Connection
  conn_params.slice!(*VALID_SUNSTONE_CONN_PARAMS)

  @connection_parameters = conn_params

  @max_identifier_length = nil
  @type_map = nil
  @raw_connection = nil
end

Class Method Details

.initialize_type_map(m) ⇒ Object

:nodoc:



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 226

def self.initialize_type_map(m) # :nodoc:
  m.register_type               'boolean',    Type::Boolean.new
  m.register_type               'binary'      do |_, options|
    Sunstone::Type::Binary.new(**options.slice(:limit))
  end
  m.register_type               'datetime',   Sunstone::Type::DateTime.new
  m.register_type               'decimal'     do |_, options|
    Type::Decimal.new(**options.slice(:precision, :scale))
  end
  m.register_type               'integer'     do |_, options|
    Type::Integer.new(**options.slice(:limit))
  end
  m.register_type               'json',       Sunstone::Type::Json.new
  m.register_type               'string'      do |_, options|
    Type::String.new(**options.slice(:limit))
  end
  m.register_type               'uuid',       Sunstone::Type::Uuid.new

  if defined?(Sunstone::Type::EWKB)
    m.register_type 'ewkb',       Sunstone::Type::EWKB.new
  end
end

.new_client(conn_params) ⇒ Object



44
45
46
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 44

def new_client(conn_params)
  ::Sunstone::Connection.new(conn_params)
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


96
97
98
99
100
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 96

def active?
  @lock.synchronize do
    @raw_connection&.active?
  end
end

#arel_visitorObject



144
145
146
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 144

def arel_visitor
  Arel::Visitors::Sunstone.new
end

#clear_cache!(new_connection: false) ⇒ Object



64
65
66
67
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 64

def clear_cache!(new_connection: false)
  # TODO move @definitions to using @schema_cache
  @definitions = {}
end

#collectorObject



148
149
150
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 148

def collector
  Arel::Collectors::Sunstone.new
end

#configure_connectionObject

Configures the encoding, verbosity, schema search path, and time zone of the connection. This is called by #connect and should not be called manually.



202
203
204
205
206
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 202

def configure_connection
  super
  
  reload_type_map
end

#connectObject

Connects to a StandardAPI server and sets up the adapter depending on the connected server's characteristics.



104
105
106
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 104

def connect
  @raw_connection = self.class.new_client(@connection_parameters)
end

#default_prepared_statementsObject



60
61
62
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 60

def default_prepared_statements
  false
end

#discard!Object

:nodoc:



123
124
125
126
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 123

def discard! # :nodoc:
  super
  @raw_connection = nil
end

#disconnect!Object



115
116
117
118
119
120
121
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 115

def disconnect!
  @lock.synchronize do
    super
    @raw_connection&.disconnect!
    @raw_connection = nil
  end
end

#insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [], returning: nil) ⇒ Object Also known as: create

Executes an INSERT query and returns a hash of the object and any updated relations. This is different from AR which returns an ID



195
196
197
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 195

def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [], returning: nil)
  exec_insert(arel, name, binds, pk, sequence_name, returning: returning)
end

#lookup_cast_type_from_column(column) ⇒ Object

:nodoc:



162
163
164
165
166
167
168
169
170
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 162

def lookup_cast_type_from_column(column) # :nodoc:
  verify! if type_map.nil?
  cast_type = @type_map.lookup(column.sql_type, {
    limit: column.limit,
    precision: column.precision,
    scale: column.scale
  })
  column.array ? Sunstone::Type::Array.new(cast_type) : cast_type
end

#native_database_typesObject

Signature:

  • nodoc:



128
129
130
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 128

def native_database_types #:nodoc:
  NATIVE_DATABASE_TYPES
end

#reconnectObject



108
109
110
111
112
113
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 108

def reconnect
  @lock.synchronize do
    @raw_connection&.reconnect!
    connect unless @raw_connection
  end
end

#reload_type_mapObject



208
209
210
211
212
213
214
215
216
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 208

def reload_type_map
  if @type_map
    type_map.clear
  else
    @type_map = Type::HashLookupTypeMap.new
  end

  initialize_type_map
end

#return_value_after_insert?(column) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


158
159
160
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 158

def return_value_after_insert?(column) # :nodoc:
  column.auto_populated?
end

#server_configObject



152
153
154
155
156
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 152

def server_config
  with_raw_connection do |conn|
    JSON.parse(conn.get("/configuration").body)
  end
end

#supports_json?Boolean

Returns:

  • (Boolean)


189
190
191
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 189

def supports_json?
  true
end

#supports_statement_cache?Boolean

include Savepoints

Returns:

  • (Boolean)


56
57
58
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 56

def supports_statement_cache?
  false
end

#transaction(requires_new: nil, isolation: nil, joinable: true) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 172

def transaction(requires_new: nil, isolation: nil, joinable: true)
  Thread.current[:sunstone_transaction_count] ||= 0
  Thread.current[:sunstone_request_sent] = nil if Thread.current[:sunstone_transaction_count] == 0
  Thread.current[:sunstone_transaction_count] += 1
  begin
    yield
  ensure
    Thread.current[:sunstone_transaction_count] -= 1
    if Thread.current[:sunstone_transaction_count] == 0
      Thread.current[:sunstone_transaction_count] = nil
      Thread.current[:sunstone_request_sent] = nil
    end
  end
rescue ActiveRecord::Rollback
  # rollbacks are silently swallowed
end

#update_table_definition(table_name, base) ⇒ Object

Signature:

  • nodoc:



140
141
142
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 140

def update_table_definition(table_name, base) #:nodoc:
  SunstoneAPI::Table.new(table_name, base)
end

#url(path = nil) ⇒ Object



92
93
94
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 92

def url(path=nil)
  "http#{@connection_parameters[:use_ssl] ? 's' : ''}://#{@connection_parameters[:host]}#{@connection_parameters[:port] != 80 ? (@connection_parameters[:port] == 443 && @connection_parameters[:use_ssl] ? '' : ":#{@connection_parameters[:port]}") : ''}#{path}"
end

#use_insert_returning?Boolean

Returns:

  • (Boolean)


132
133
134
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 132

def use_insert_returning?
  true
end

#valid_type?(type) ⇒ Boolean

Returns:

  • (Boolean)


136
137
138
# File 'lib/active_record/connection_adapters/sunstone_adapter.rb', line 136

def valid_type?(type)
  !native_database_types[type].nil?
end