Class: Cassie::Schema

Inherits:
Object
  • Object
show all
Defined in:
lib/cassie/schema.rb

Overview

This class can be used to create, drop, or get information about the cassandra schemas. This class is intended only to provide support for creating schemas in development and test environments. You should not use this class with your production environment since some of the methods can be destructive.

The schemas are organized by keyspace.

To load schemas for test and development environments you should specify a directory where the schema definition files live. The files should be named “#abstract_keyspace.cql”. The actual keyspace name will be looked from the keyspace mapping in the configuration.

Constant Summary collapse

TABLES_CQL =
"SELECT columnfamily_name FROM system.schema_columnfamilies WHERE keyspace_name = ?".freeze
CREATE_MATCHER =
/\A(?<create>CREATE (TABLE|((CUSTOM )?INDEX)|TYPE|TRIGGER))(?<exist>( IF NOT EXISTS)?) (?<object>[a-z0-9_.]+)/i.freeze
DROP_MATCHER =
/\A(?<drop>DROP (TABLE|INDEX|TYPE|TRIGGER))(?<exist>( IF EXISTS)?) (?<object>[a-z0-9_.]+)/i.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(keyspace) ⇒ Schema

Returns a new instance of Schema.



107
108
109
# File 'lib/cassie/schema.rb', line 107

def initialize(keyspace)
  @keyspace = keyspace
end

Instance Attribute Details

#keyspaceObject (readonly)

Returns the value of attribute keyspace.



16
17
18
# File 'lib/cassie/schema.rb', line 16

def keyspace
  @keyspace
end

Class Method Details

.allObject

Get all the defined schemas.



20
21
22
# File 'lib/cassie/schema.rb', line 20

def all
  schemas.values
end

.drop!(keyspace_name) ⇒ Object

Drop a specified keyspace by abstract name. The actual keyspace name will be looked up from the keyspaces in the configuration.

Raises:

  • (ArgumentError)


36
37
38
39
40
41
42
# File 'lib/cassie/schema.rb', line 36

def drop!(keyspace_name)
  keyspace = Cassie.instance.config.keyspace(keyspace_name)
  raise ArgumentError.new("#{keyspace_name} is not defined as keyspace in the configuration") unless keyspace
  
  drop_keyspace_cql = "DROP KEYSPACE IF EXISTS #{keyspace}"
  Cassie.instance.execute(drop_keyspace_cql)
end

.drop_all!Object

Drop all keyspaces defined in the configuration.



80
81
82
83
84
# File 'lib/cassie/schema.rb', line 80

def drop_all!
  Cassie.instance.config.keyspace_names.each do |keyspace|
    drop!(keyspace)
  end
end

.find(keyspace) ⇒ Object

Find the schema for a keyspace using the abstract name.



25
26
27
# File 'lib/cassie/schema.rb', line 25

def find(keyspace)
  schemas[keyspace]
end

.load!(keyspace_name) ⇒ Object

Load a specified keyspace by abstract name. The actual keyspace name will be looked up from the keyspaces in the configuration.

Raises:

  • (ArgumentError)


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/cassie/schema.rb', line 46

def load!(keyspace_name)
  keyspace = Cassie.instance.config.keyspace(keyspace_name)
  raise ArgumentError.new("#{keyspace_name} is not defined as keyspace in the configuration") unless keyspace

  schema_file = File.join(Cassie.instance.config.schema_directory, "#{keyspace_name}.cql")
  raise ArgumentError.new("#{keyspace_name} schema file does not exist at #{schema_file}") unless File.exist?(schema_file)
  schema_statements = File.read(schema_file).split(';').collect{|s| s.strip.chomp(';')}
  
  create_keyspace_cql = "CREATE KEYSPACE IF NOT EXISTS #{keyspace} WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1}"
  Cassie.instance.execute(create_keyspace_cql)
  
  schema_statements.each do |statement|
    statement = statement.gsub(/#(.*)$/, '').gsub(/\s+/, ' ').strip
    create_match = statement.match(CREATE_MATCHER)
    if create_match
      object = create_match["object"]
      object = "#{keyspace}.#{object}" unless object.include?('.')
      statement = statement.sub(create_match.to_s, "#{create_match['create']} IF NOT EXISTS #{object}")
    else
      drop_match = statement.match(DROP_MATCHER)
      if drop_match
        object = drop_match["object"]
        object = "#{keyspace}.#{object}" unless object.include?('.')
        statement = statement.sub(drop_match.to_s, "#{drop_match['drop']} IF EXISTS #{object}")
      end
    end
    unless statement.blank?
      Cassie.instance.execute(statement)
    end
  end
  nil
end

.load_all!Object

Drop all keyspaces defined in the configuration.



87
88
89
90
91
# File 'lib/cassie/schema.rb', line 87

def load_all!
  Cassie.instance.config.keyspace_names.each do |keyspace|
    load!(keyspace)
  end
end

.reset!Object

Throw out the cached schemas so they can be reloaded from the configuration.



30
31
32
# File 'lib/cassie/schema.rb', line 30

def reset!
  @schemas = nil
end

Instance Method Details

#tablesObject

Returns a list of tables defined for the schema.



112
113
114
115
116
117
118
119
120
121
122
# File 'lib/cassie/schema.rb', line 112

def tables
  unless defined?(@tables) && @tables
    tables = []
    results = Cassie.instance.execute(TABLES_CQL, keyspace)
    results.each do |row|
      tables << row['columnfamily_name']
    end
    @tables = tables
  end
  @tables
end

#truncate!(table) ⇒ Object

Truncate the data from a table.



125
126
127
128
# File 'lib/cassie/schema.rb', line 125

def truncate!(table)
  statement = Cassie.instance.prepare("TRUNCATE #{keyspace}.#{table}")
  Cassie.instance.execute(statement)
end