class CrateRuby::Client
Client
to interact with Crate.io DB
Constants
- DEFAULT_HOST
- DEFAULT_PORT
Attributes
Public Class Methods
Currently only a single server is supported. Fail over will be implemented in upcoming versions @param [Array] servers An Array of servers including ports [127.0.0.1:4200, 10.0.0.1:4201] @param [opts] opts Optional parameters
-
logger: Custom Logger
-
http_options [Hash]: Net::HTTP options (open_timeout, read_timeout)
-
schema [String]: Default schema to search in
@return [CrateRuby::Client]
# 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
Public Instance Methods
Delete blob @param [String] table @param [String] digest SHA1 hexdigest
@return [Boolean]
# 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
Download blob @param [String] table @param [String] digest SHA1 hexdigest
@return [Blob] File data to write to file or use directly
# 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
Upload a File to a blob table @param [String] table @param [String] digest SHA1 hexdigest @param [Boolean] data Can be any payload object that can be sent via HTTP, e.g. STRING, FILE
# 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
Returns all tables in schema 'blob' @return [Array<String>] Array of blob tables
# 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
Creates a table for storing blobs @param [String] name Table name @param [Integer] shard_count Shard count, defaults to 5 @param [Integer] replicas Number of replicas, defaults to 0 @return [ResultSet]
client.create_blob_table(“blob_table”)
# 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
Creates a table
client.create_table "posts", id: [:integer, "primary key"], my_column: :string, my_integer_col: :integer
@param [String] table_name @param [Hash] column_definition @option column_definition [String] key sets column name, value sets column type. an array passed as value can be used to set options like primary keys @return [ResultSet]
# 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 @param [String] table_name, Name of table to drop @param [Boolean] blob Needs to be set to true if table is a blob table @return [ResultSet]
# 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
Executes a SQL statement against the Crate HTTP REST endpoint. @param [String] sql statement to execute @param [Array] args Array of values used for parameter substitution @param [Array] bulk_args List of lists containing records to be processed @param [Hash] http_options Net::HTTP options (open_timeout, read_timeout) @return [ResultSet]
# 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
# 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
# File lib/crate_ruby/client.rb, line 51 def inspect %(#<CrateRuby::Client:#{object_id}>) end
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 @param [String] table_name Name of table to refresh
# File lib/crate_ruby/client.rb, line 212 def refresh_table(table_name) execute "refresh table #{table_name}" end
List all user tables @return [ResultSet]
# File lib/crate_ruby/client.rb, line 93 def show_tables execute('select table_name from information_schema.tables where table_schema = ?', [schema]) end
Return the table structure @param [String] table_name Table name to get structure @param [ResultSet]
# 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
Returns all tables in schema 'doc' @return [Array<String>] Array of table names
# 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
Private Instance Methods
# File lib/crate_ruby/client.rb, line 218 def blob_path(table, digest) "/_blobs/#{table}/#{digest}" end
# File lib/crate_ruby/client.rb, line 222 def connection host, port = @servers.first.split(':') http = Net::HTTP.new(host, port) http.use_ssl = true if @ssl return http end
# File lib/crate_ruby/client.rb, line 245 def encrypted_credentials @encrypted_credentials ||= Base64.encode64 "#{username}:#{password}" end
# File lib/crate_ruby/client.rb, line 237 def headers header = { 'Content-Type' => 'application/json', 'Accept' => 'application/json' } header['Default-Schema'] = schema if schema header['Authorization'] = "Basic #{encrypted_credentials}" if username header['X-User'] = username if username # for backwards compatibility with Crate 2.2 header end
# File lib/crate_ruby/client.rb, line 229 def request(req, http_options = {}) options = @http_options.merge(http_options) connection.start do |http| options.each { |opt, value| http.send("#{opt}=", value) } http.request(req) end end