lib/cequel/schema/table_writer.rb
# -*- encoding : utf-8 -*-
module Cequel
module Schema
#
# Creates a new table schema in the database
#
class TableWriter
#
# Creates a new table schema in the database given an object
# representation of the schema to create
#
# @param (see #initialize)
# @return (see #apply)
#
def self.apply(keyspace, table)
new(table).apply(keyspace)
end
#
# @param keyspace [Keyspace] keyspace in which to create the table
# @param table [Table] object representation of table schema
#
def initialize(table)
@table = table
end
#
# Create the table in the keyspace
#
# @return [void]
#
# @api private
#
def apply(keyspace)
statements.each { |statement| keyspace.execute(statement) }
end
def statements
[create_statement] + index_statements
end
protected
attr_reader :table
private
def create_statement
"CREATE TABLE #{table.name} (#{columns_cql}, #{keys_cql})".tap do |cql|
properties = properties_cql
cql << " WITH #{properties}" if properties
end
end
def index_statements
[].tap do |statements|
table.data_columns.each do |column|
if column.indexed?
statements <<
"CREATE INDEX #{column.index_name} " \
"ON #{table.name} (#{column.name})"
end
end
end
end
def columns_cql
table.columns.map(&:to_cql).join(', ')
end
def key_columns_cql
table.keys.map(&:to_cql).join(', ')
end
def keys_cql
partition_cql = table.partition_key_columns
.map { |key| key.name }.join(', ')
if table.clustering_columns.any?
nonpartition_cql =
table.clustering_columns.map { |key| key.name }.join(', ')
"PRIMARY KEY ((#{partition_cql}), #{nonpartition_cql})"
else
"PRIMARY KEY ((#{partition_cql}))"
end
end
def properties_cql
properties_fragments = table.properties
.map { |_, property| property.to_cql }
properties_fragments << 'COMPACT STORAGE' if table.compact_storage?
if table.clustering_columns.any?
clustering_fragment =
table.clustering_columns.map(&:clustering_order_cql).join(',')
properties_fragments <<
"CLUSTERING ORDER BY (#{clustering_fragment})"
end
properties_fragments.join(' AND ') if properties_fragments.any?
end
end
end
end