Class: CrateRuby::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/crate_ruby/client.rb

Overview

Client to interact with Crate.io DB

Constant Summary collapse

DEFAULT_HOST =
'127.0.0.1'
DEFAULT_PORT =
'4200'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(servers = [], opts = {}) ⇒ CrateRuby::Client

Currently only a single server is supported. Fail over will be implemented in upcoming versions

  • logger: Custom Logger

  • http_options [Hash]: Net::HTTP options (open_timeout, read_timeout)

  • schema [String]: Default schema to search in

Parameters:

  • servers (Array) (defaults to: [])

    An Array of servers including ports [127.0.0.1:4200, 10.0.0.1:4201]

  • opts (opts) (defaults to: {})

    Optional parameters



42
43
44
45
46
47
48
49
50
51
# File 'lib/crate_ruby/client.rb', line 42

def initialize(servers = [], opts = {})
  @servers = servers
  @servers << "#{DEFAULT_HOST}:#{DEFAULT_PORT}" if servers.empty?
  @logger = opts[:logger] || CrateRuby.logger
  @http_options = opts[:http_options] || { read_timeout: 3600 }
  @schema = opts[:schema] || 'doc'
  @username = opts[:username]
  @password = opts[:password]
  @ssl = opts[:ssl] || false
end

Instance Attribute Details

#loggerObject

Returns the value of attribute logger.



33
34
35
# File 'lib/crate_ruby/client.rb', line 33

def logger
  @logger
end

#passwordObject

Returns the value of attribute password.



33
34
35
# File 'lib/crate_ruby/client.rb', line 33

def password
  @password
end

#schemaObject

Returns the value of attribute schema.



33
34
35
# File 'lib/crate_ruby/client.rb', line 33

def schema
  @schema
end

#usernameObject

Returns the value of attribute username.



33
34
35
# File 'lib/crate_ruby/client.rb', line 33

def username
  @username
end

Instance Method Details

#blob_delete(table, digest) ⇒ Boolean

Delete blob

Parameters:

  • table (String)
  • digest (String)

    SHA1 hexdigest

Returns:

  • (Boolean)


179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/crate_ruby/client.rb', line 179

def blob_delete(table, digest)
  uri = blob_path(table, digest)
  @logger.debug("BLOB DELETE #{uri}")
  req = Net::HTTP::Delete.new(uri, headers)
  response = request(req)
  case response.code
  when '200'
    true
  else
    @logger.info("Response #{response.code}: #{response.body}")
    false
  end
end

#blob_get(table, digest) ⇒ Blob

Download blob

Parameters:

  • table (String)
  • digest (String)

    SHA1 hexdigest

Returns:

  • (Blob)

    File data to write to file or use directly



160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/crate_ruby/client.rb', line 160

def blob_get(table, digest)
  uri = blob_path(table, digest)
  @logger.debug("BLOB GET #{uri}")
  req = Net::HTTP::Get.new(uri, headers)
  response = request(req)
  case response.code
  when '200'
    response.body
  else
    @logger.info("Response #{response.code}: #{response.body}")
    false
  end
end

#blob_put(table, digest, data) ⇒ Object

Upload a File to a blob table

Parameters:

  • table (String)
  • digest (String)

    SHA1 hexdigest

  • data (Boolean)

    Can be any payload object that can be sent via HTTP, e.g. STRING, FILE



140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/crate_ruby/client.rb', line 140

def blob_put(table, digest, data)
  uri = blob_path(table, digest)
  @logger.debug("BLOB PUT #{uri}")
  req = Net::HTTP::Put.new(blob_path(table, digest), headers)
  req.body = data
  response = request(req)
  case response.code
  when '201'
    true
  else
    @logger.info("Response #{response.code}: " + response.body)
    false
  end
end

#blob_tablesArray<String>

Returns all tables in schema ‘blob’

Returns:

  • (Array<String>)

    Array of blob tables



107
108
109
# File 'lib/crate_ruby/client.rb', line 107

def blob_tables
  execute('select table_name from information_schema.tables where table_schema = ?', ['blob']).map(&:first)
end

#create_blob_table(name, shard_count = 5, replicas = 0) ⇒ ResultSet

Creates a table for storing blobs client.create_blob_table(“blob_table”)

Parameters:

  • name (String)

    Table name

  • shard_count (Integer) (defaults to: 5)

    Shard count, defaults to 5

  • replicas (Integer) (defaults to: 0)

    Number of replicas, defaults to 0

Returns:



78
79
80
81
# File 'lib/crate_ruby/client.rb', line 78

def create_blob_table(name, shard_count = 5, replicas = 0)
  stmt = %{CREATE BLOB TABLE "#{name}" CLUSTERED INTO ? SHARDS WITH (number_of_replicas=?)}
  execute stmt, [shard_count, replicas]
end

#create_table(table_name, column_definition = {}) ⇒ ResultSet

Creates a table

client.create_table "posts", id: [:integer, "primary key"], my_column: :string, my_integer_col: :integer

be used to set options like primary keys

Parameters:

  • table_name (String)
  • column_definition (Hash) (defaults to: {})

Options Hash (column_definition):

  • key (String)

    sets column name, value sets column type. an array passed as value can

Returns:



65
66
67
68
69
# File 'lib/crate_ruby/client.rb', line 65

def create_table(table_name, column_definition = {})
  cols = column_definition.to_a.map { |a| a.join(' ') }.join(', ')
  stmt = %{CREATE TABLE "#{table_name}" (#{cols})}
  execute(stmt)
end

#drop_table(table_name, blob = false) ⇒ ResultSet

Drop table

Parameters:

  • table_name, (String)

    Name of table to drop

  • blob (Boolean) (defaults to: false)

    Needs to be set to true if table is a blob table

Returns:



87
88
89
90
91
# File 'lib/crate_ruby/client.rb', line 87

def drop_table(table_name, blob = false)
  tbl = blob ? 'BLOB TABLE' : 'TABLE'
  stmt = %(DROP #{tbl} "#{table_name}")
  execute(stmt)
end

#execute(sql, args = nil, bulk_args = nil, http_options = {}) ⇒ ResultSet

Executes a SQL statement against the Crate HTTP REST endpoint.

Parameters:

  • sql (String)

    statement to execute

  • args (Array) (defaults to: nil)

    Array of values used for parameter substitution

  • bulk_args (Array) (defaults to: nil)

    List of lists containing records to be processed

  • http_options (Hash) (defaults to: {})

    Net::HTTP options (open_timeout, read_timeout)

Returns:



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/crate_ruby/client.rb', line 117

def execute(sql, args = nil, bulk_args = nil, http_options = {})
  @logger.debug sql
  req = Net::HTTP::Post.new('/_sql', headers)
  body = { 'stmt' => sql }
  body['args'] = args if args
  body['bulk_args'] = bulk_args if bulk_args
  req.body = body.to_json
  response = request(req, http_options)
  @logger.debug response.body

  case response.code
  when /^2\d{2}/
    ResultSet.new response.body
  else
    @logger.info(response.body)
    raise CrateRuby::CrateError, response.body
  end
end

#insert(table_name, attributes) ⇒ Object



201
202
203
204
205
206
207
# File 'lib/crate_ruby/client.rb', line 201

def insert(table_name, attributes)
  vals = attributes.values
  identifiers = attributes.keys.map { |v| %("#{v}") }.join(', ')
  binds = vals.count.times.map { |i| "$#{i + 1}" }.join(',')
  stmt = %{INSERT INTO "#{table_name}" (#{identifiers}) VALUES(#{binds})}
  execute(stmt, vals)
end

#inspectObject



53
54
55
# File 'lib/crate_ruby/client.rb', line 53

def inspect
  %(#<CrateRuby::Client:#{object_id}>)
end

#refresh_table(table_name) ⇒ Object

Crate is eventually consistent, If you don’t query by primary key, it is not guaranteed that an insert record is found on the next query. Default refresh value is 1000ms. Using refresh_table you can force a refresh

Parameters:

  • table_name (String)

    Name of table to refresh



214
215
216
# File 'lib/crate_ruby/client.rb', line 214

def refresh_table(table_name)
  execute "refresh table #{table_name}"
end

#show_tablesResultSet

List all user tables

Returns:



95
96
97
# File 'lib/crate_ruby/client.rb', line 95

def show_tables
  execute('select table_name from information_schema.tables where table_schema = ?', [schema])
end

#table_structure(table_name) ⇒ Object

Return the table structure

Parameters:

  • table_name (String)

    Table name to get structure

  • (ResultSet)


196
197
198
199
# File 'lib/crate_ruby/client.rb', line 196

def table_structure(table_name)
  execute('select * from information_schema.columns where table_schema = ?' \
          'AND table_name = ?', [schema, table_name])
end

#tablesArray<String>

Returns all tables in schema ‘doc’

Returns:

  • (Array<String>)

    Array of table names



101
102
103
# File 'lib/crate_ruby/client.rb', line 101

def tables
  execute('select table_name from information_schema.tables where table_schema = ?', [schema]).map(&:first)
end