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
49
# 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]
  @ssl = opts[:ssl] || false
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)


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

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



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

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



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

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



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

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:



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

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:



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

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:



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

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:



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

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



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

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



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

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



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

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

#show_tablesResultSet

List all user tables

Returns:



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

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)


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

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



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

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