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'.freeze
DEFAULT_PORT =
'4200'.freeze

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



40
41
42
43
44
45
46
47
48
# File 'lib/crate_ruby/client.rb', line 40

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]
end

Instance Attribute Details

#loggerObject

Returns the value of attribute logger.



31
32
33
# File 'lib/crate_ruby/client.rb', line 31

def logger
  @logger
end

#passwordObject

Returns the value of attribute password.



31
32
33
# File 'lib/crate_ruby/client.rb', line 31

def password
  @password
end

#schemaObject

Returns the value of attribute schema.



31
32
33
# File 'lib/crate_ruby/client.rb', line 31

def schema
  @schema
end

#usernameObject

Returns the value of attribute username.



31
32
33
# File 'lib/crate_ruby/client.rb', line 31

def username
  @username
end

Instance Method Details

#blob_delete(table, digest) ⇒ Boolean

Delete blob

Parameters:

  • table (String)
  • digest (String)

    SHA1 hexdigest

Returns:

  • (Boolean)


176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/crate_ruby/client.rb', line 176

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



157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/crate_ruby/client.rb', line 157

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



137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/crate_ruby/client.rb', line 137

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



104
105
106
# File 'lib/crate_ruby/client.rb', line 104

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:



75
76
77
78
# File 'lib/crate_ruby/client.rb', line 75

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:



62
63
64
65
66
# File 'lib/crate_ruby/client.rb', line 62

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:



84
85
86
87
88
# File 'lib/crate_ruby/client.rb', line 84

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:



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

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



198
199
200
201
202
203
204
# File 'lib/crate_ruby/client.rb', line 198

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



50
51
52
# File 'lib/crate_ruby/client.rb', line 50

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



211
212
213
# File 'lib/crate_ruby/client.rb', line 211

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

#show_tablesResultSet

List all user tables

Returns:



92
93
94
# File 'lib/crate_ruby/client.rb', line 92

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)


193
194
195
196
# File 'lib/crate_ruby/client.rb', line 193

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



98
99
100
# File 'lib/crate_ruby/client.rb', line 98

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