Module: Cql::Client

Defined in:
lib/cql/client.rb,
lib/cql/client/batch.rb,
lib/cql/client/client.rb,
lib/cql/client/connector.rb,
lib/cql/client/null_logger.rb,
lib/cql/client/void_result.rb,
lib/cql/client/query_result.rb,
lib/cql/client/peer_discovery.rb,
lib/cql/client/request_runner.rb,
lib/cql/client/column_metadata.rb,
lib/cql/client/result_metadata.rb,
lib/cql/client/keyspace_changer.rb,
lib/cql/client/connection_manager.rb,
lib/cql/client/prepared_statement.rb,
lib/cql/client/execute_options_decoder.rb

Overview

A CQL client manages connections to one or more Cassandra nodes and you use it run queries, insert and update data.

Client instances are threadsafe.

See Client for the full client API, or Client.connect for the options available when connecting.

Examples:

Connecting and changing to a keyspace

# create a client and connect to two Cassandra nodes
client = Cql::Client.connect(hosts: %w[node01.cassandra.local node02.cassandra.local])
# change to a keyspace
client.use('stuff')

Query for data

rows = client.execute('SELECT * FROM things WHERE id = 2')
rows.each do |row|
  p row
end

Inserting and updating data

client.execute("INSERT INTO things (id, value) VALUES (4, 'foo')")
client.execute("UPDATE things SET value = 'bar' WHERE id = 5")

Prepared statements

statement = client.prepare('INSERT INTO things (id, value) VALUES (?, ?)')
statement.execute(9, 'qux')
statement.execute(8, 'baz')

Defined Under Namespace

Classes: Batch, Client, ColumnMetadata, PreparedStatement, PreparedStatementBatch, QueryResult, ResultMetadata, VoidResult

Constant Summary collapse

InvalidKeyspaceNameError =
Class.new(ClientError)

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.connect(options = {}) ⇒ Cql::Client::Client

Create a new client and connect to Cassandra.

By default the client will connect to localhost port 9042, which can be overridden with the :hosts and :port options, respectively. Once connected to the hosts given in :hosts the rest of the nodes in the cluster will automatically be discovered and connected to.

If you have a multi data center setup the client will connect to all nodes in the data centers where the nodes you pass to :hosts are located. So if you only want to connect to nodes in one data center, make sure that you only specify nodes in that data center in :hosts.

The connection will succeed if at least one node is up and accepts the connection. Nodes that don't respond within the specified timeout, or where the connection initialization fails for some reason, are ignored.

Parameters:

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

Options Hash (options):

  • :hosts (Array<String>) — default: ['localhost']

    One or more hostnames used as seed nodes when connecting. Duplicates will be removed.

  • :port (String) — default: 9042

    The port to connect to, this port will be used for all nodes. Because the system.peers table does not contain the port that the nodes are listening on, the port must be the same for all nodes.

  • :connection_timeout (Integer) — default: 5

    Max time to wait for a connection, in seconds.

  • :keyspace (String)

    The keyspace to change to immediately after all connections have been established, this is optional.

  • :credentials (Hash)

    When using Cassandra's built in authentication you can provide your username and password through this option. Example: :credentials => {:username => 'cassandra', :password => 'cassandra'}

  • :auth_provider (Object)

    When using custom authentication use this option to specify the auth provider that will handle the authentication negotiation. See AuthProvider for more info.

  • :connections_per_node (Integer) — default: 1

    The number of connections to open to each node. Each connection can have 128 concurrent requests, so unless you have a need for more than that (times the number of nodes in your cluster), leave this option at its default.

  • :default_consistency (Integer) — default: :quorum

    The consistency to use unless otherwise specified. Consistency can also be specified on a per-request basis.

  • :compressor (Cql::Compression::Compressor)

    An object that can compress and decompress frames. By specifying this option frame compression will be enabled. If the server does not support compression or the specific compression algorithm specified by the compressor, compression will not be enabled and a warning will be logged.

  • :cql_version (String)

    Specifies which CQL version the server should expect.

  • :logger (Integer)

    If you want the client to log significant events pass an object implementing the standard Ruby logger interface (e.g. quacks like Logger from the standard library) with this option.

Returns:

Raises:

  • Cql::Io::ConnectionError when a connection couldn't be established to any node

  • Cql::Client::QueryError when the specified keyspace does not exist or when the specifed CQL version is not supported.



131
132
133
# File 'lib/cql/client.rb', line 131

def self.connect(options={})
  SynchronousClient.new(AsynchronousClient.new(options)).connect
end

Instance Method Details

#add(*bound_values) ⇒ nil

Add the statement to the batch with the specified bound values.

Parameters:

Returns:

  • (nil)


# File 'lib/cql/client/batch.rb', line 13

#batch(type = :logged, options = {}) {|batch| ... } ⇒ Cql::Client::VoidResult, Cql::Client::Batch

Yields a batch when called with a block. The batch is automatically executed at the end of the block and the result is returned.

Returns a batch when called wihtout a block. The batch will remember the options given and merge these with any additional options given when Cql::Client::Batch#execute is called.

Please note that the batch object returned by this method is not thread safe.

The type parameter can be ommitted and the options can then be given as first parameter.

Examples:

Executing queries in a batch

client.batch do |batch|
  batch.add(%(INSERT INTO metrics (id, time, value) VALUES (1234, NOW(), 23423)))
  batch.add(%(INSERT INTO metrics (id, time, value) VALUES (2346, NOW(), 13)))
  batch.add(%(INSERT INTO metrics (id, time, value) VALUES (2342, NOW(), 2367)))
  batch.add(%(INSERT INTO metrics (id, time, value) VALUES (4562, NOW(), 1231)))
end

Using the returned batch object

batch = client.batch(:counter, trace: true)
batch.add('UPDATE counts SET value = value + ? WHERE id = ?', 4, 87654)
batch.add('UPDATE counts SET value = value + ? WHERE id = ?', 3, 6572)
result = batch.execute(timeout: 10)
puts result.trace_id

Providing type hints for on-the-fly bound values

batch = client.batch
batch.add('UPDATE counts SET value = value + ? WHERE id = ?', 4, type_hints: [:int])
batch.execute

Parameters:

  • type (Symbol) (defaults to: :logged)

    the type of batch, must be one of :logged, :unlogged and :counter. The precise meaning of these is defined in the CQL specification.

Yield Parameters:

Returns:

See Also:



# File 'lib/cql/client/client.rb', line 165

#closeCql::Client

Disconnect from all nodes.

Returns:



# File 'lib/cql/client/client.rb', line 28

#connected?true, false

Returns whether or not the client is connected.

Returns:

  • (true, false)


# File 'lib/cql/client/client.rb', line 34

#execute(cql, *values, options = {}) ⇒ nil, ...

Execute a CQL statement, optionally passing bound values.

When passing bound values the request encoder will have to guess what types to encode the values as. For most types this will be no problem, but for integers and floating point numbers the larger size will be chosen (e.g. BIGINT and DOUBLE and not INT and FLOAT). You can override the guessing with the :type_hint option. Don't use on-the-fly bound values when you will issue the request multiple times, prepared statements are almost always a better choice.

Please note that on-the-fly bound values are only supported by Cassandra 2.0 and above.

Examples:

A simple CQL query

result = client.execute("SELECT * FROM users WHERE user_name = 'sue'")
result.each do |row|
  p row
end

Using on-the-fly bound values

client.execute('INSERT INTO users (user_name, full_name) VALUES (?, ?)', 'sue', 'Sue Smith')

Using on-the-fly bound values with type hints

client.execute('INSERT INTO users (user_name, age) VALUES (?, ?)', 'sue', 33, type_hints: [nil, :int])

Specifying the consistency as a symbol

client.execute("UPDATE users SET full_name = 'Sue S. Smith' WHERE user_name = 'sue'", consistency: :one)

Specifying the consistency and other options

client.execute("SELECT * FROM users", consistency: :all, timeout: 1.5)

Loading a big result page by page

result_page = client.execute("SELECT * FROM large_table WHERE id = 'partition_with_lots_of_data'", page_size: 100)
while result_page
  result_page.each do |row|
    p row
  end
  result_page = result_page.next_page
end

Activating tracing for a query

result = client.execute("SELECT * FROM users", tracing: true)
p result.trace_id

Parameters:

  • cql (String)
  • values (Array)

    Values to bind to any binding markers in the query (i.e. "?" placeholders) -- using this feature is similar to using a prepared statement, but without the type checking. The client needs to guess which data types to encode the values as, and will err on the side of caution, using types like BIGINT instead of INT for integers, and DOUBLE instead of FLOAT for floating point numbers. It is not recommended to use this feature for anything but convenience, and the algorithm used to guess types is to be considered experimental.

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

Options Hash (options):

  • :consistency (Symbol) — default: :quorum

    The consistency to use for this query.

  • :serial_consistency (Symbol) — default: nil

    The consistency to use for conditional updates (:serial or :local_serial), see the CQL documentation for the semantics of serial consistencies and conditional updates. The default is assumed to be :serial by the server if none is specified. Ignored for non- conditional queries.

  • :timeout (Integer) — default: nil

    How long to wait for a response. If this timeout expires a TimeoutError will be raised.

  • :trace (Boolean) — default: false

    Request tracing for this request. See QueryResult and VoidResult for how to retrieve the tracing data.

  • :page_size (Integer) — default: nil

    Instead of returning all rows, return the response in pages of this size. The first result will contain the first page, to load subsequent pages use Cql::Client::QueryResult#next_page.

  • :type_hints (Array) — default: nil

    When passing on-the-fly bound values the request encoder will have to guess what types to encode the values as. Using this option you can give it hints and avoid it guessing wrong. The hints must be an array that has the same number of arguments as the number of bound values, and each element should be the type of the corresponding value, or nil if you prefer the encoder to guess. The types should be provided as lower case symbols, e.g. :int, :time_uuid, etc.

Returns:

Raises:

  • (Cql::NotConnectedError)

    raised when the client is not connected

  • (Cql::TimeoutError)

    raised when a timeout was specified and no response was received within the timeout.

  • (Cql::QueryError)

    raised when the CQL has syntax errors or for other situations when the server complains.



# File 'lib/cql/client/batch.rb', line 34

#keyspaceString

Returns the name of the current keyspace, or nil if no keyspace has been set yet.

Returns:

  • (String)


# File 'lib/cql/client/client.rb', line 40

#prepare(cql) ⇒ Cql::Client::PreparedStatement

Returns a prepared statement that can be run over and over again with different bound values.

Parameters:

  • cql (String)

    The CQL to prepare

Returns:

Raises:

  • (Cql::NotConnectedError)

    raised when the client is not connected

  • (Cql::Io::IoError)

    raised when there is an IO error, for example if the server suddenly closes the connection

  • (Cql::QueryError)

    raised when there is an error on the server side, for example when you specify a malformed CQL query

See Also:



# File 'lib/cql/client/client.rb', line 150

#use(keyspace) ⇒ nil

Changes keyspace by sending a USE statement to all connections.

The the second parameter is meant for internal use only.

Parameters:

  • keyspace (String)

Returns:

  • (nil)

Raises:



# File 'lib/cql/client/client.rb', line 47