Module: CassandraObject::Persistence::ClassMethods

Defined in:
lib/cassandra_object/persistence.rb

Instance Method Summary collapse

Instance Method Details

#add(key, value, *columns_and_options) ⇒ Object



6
7
8
9
10
11
12
13
14
# File 'lib/cassandra_object/persistence.rb', line 6

def add(key, value, *columns_and_options)
  column_family, column, sub_column, options = connection.extract_and_validate_params(self.column_family, key, columns_and_options, {})
  # the options are removed, leaving just columns
  columns = columns_and_options

  ActiveSupport::Notifications.instrument("add.cassandra_object", column_family: column_family, key: key, column: column, sub_column: sub_column, value: value) do
    connection.add(column_family, key, value, *columns, :consistency => thrift_write_consistency)
  end
end

#add_multiple_columns(key, hash, options = {}) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/cassandra_object/persistence.rb', line 16

def add_multiple_columns(key, hash, options = {})
  columns = hash.keys
  values = []
  if ! columns.empty? && hash[columns.first].is_a?(Hash)
    column_spec = hash.map { |column, sub_columns| sub_columns.keys.map { |sub_column| [column, sub_column].join('.') } }.flatten.join(', ')
    values = hash.map { |column, sub_columns| sub_columns.values }.flatten
  else
    column_spec = columns.join(', ')
    values = hash.values
  end
  values.uniq!
  value_spec = values.length == 1 ? values[0] : '<various>'

  ActiveSupport::Notifications.instrument("add.cassandra_object", column_family: column_family, key: key, column: column_spec, value: value_spec) do
    connection.add_multiple_columns(column_family, key, hash, :consistency => thrift_write_consistency)
  end
end

#column_family_configurationObject



113
114
115
# File 'lib/cassandra_object/persistence.rb', line 113

def column_family_configuration
  [{:Name => column_family, :CompareWith => "UTF8Type"}]
end

#create(attributes = {}) ⇒ Object



55
56
57
58
59
# File 'lib/cassandra_object/persistence.rb', line 55

def create(attributes = {})
  new(attributes).tap do |object|
    object.save
  end
end

#decode_columns_hash(attributes) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
# File 'lib/cassandra_object/persistence.rb', line 101

def decode_columns_hash(attributes)
  Hash[attributes.map do |k, v|
         attribute = model_attributes[k]
         decoded = if attribute.converter.method(:decode).arity == 1
                     attribute.converter.decode(v)
                   else
                     attribute.converter.decode(v, attribute.options)
                   end
         [k.to_s, decoded]
       end]
end

#delete_allObject



49
50
51
52
53
# File 'lib/cassandra_object/persistence.rb', line 49

def delete_all
  ActiveSupport::Notifications.instrument("truncate.cassandra_object", column_family: column_family) do
    connection.truncate!(column_family)
  end
end

#encode_columns_hash(attributes, schema_version) ⇒ Object



91
92
93
94
95
96
97
98
99
# File 'lib/cassandra_object/persistence.rb', line 91

def encode_columns_hash(attributes, schema_version)
  attributes.inject({}) do |memo, (column_name, value)|
    # cassandra stores bytes, not strings, so it has no concept of encodings. The ruby thrift gem 
    # expects all strings to be encoded as ascii-8bit.
    # don't attempt to encode columns that are nil
    memo[column_name.to_s] = value.nil? ? '' : model_attributes[column_name].converter.encode(value).force_encoding('ASCII-8BIT')
    memo
  end.merge({"schema_version" => schema_version.to_s})
end

#instantiate(key, attributes) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/cassandra_object/persistence.rb', line 77

def instantiate(key, attributes)
  # remove any attributes we don't know about. we would do this earlier, but we want to make such
  #  attributes available to migrations
  attributes.delete_if { |k,_| model_attributes[k].nil? }

  allocate.tap do |object|
    object.instance_variable_set("@schema_version", attributes.delete('schema_version'))
    object.instance_variable_set("@key", parse_key(key))
    object.instance_variable_set("@new_record", false)
    object.instance_variable_set("@destroyed", false)
    object.instance_variable_set("@attributes", decode_columns_hash(attributes))
  end
end

#remove(key) ⇒ Object



34
35
36
37
38
# File 'lib/cassandra_object/persistence.rb', line 34

def remove(key)
  ActiveSupport::Notifications.instrument("remove.cassandra_object", column_family: column_family, key: key) do 
    connection.remove(column_family, key.to_s, consistency: thrift_write_consistency)
  end
end

#remove_counter(key) ⇒ Object

remove_counter is not exposed by Cassandra gem. TODO: move this to Cassandra gem.



42
43
44
45
46
47
# File 'lib/cassandra_object/persistence.rb', line 42

def remove_counter(key)
  ActiveSupport::Notifications.instrument("remove.cassandra_object", column_family: column_family, key: key) do
    parent = CassandraThrift::ColumnParent.new(:column_family => column_family)
    connection.send(:client).remove_counter(key, parent, thrift_write_consistency)
  end
end

#write(key, attributes, schema_version) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/cassandra_object/persistence.rb', line 61

def write(key, attributes, schema_version)
  key.tap do |key|
    unless attributes.blank?
      attributes = encode_columns_hash(attributes, schema_version)
      ActiveSupport::Notifications.instrument("insert.cassandra_object", column_family: column_family, key: key, attributes: attributes) do
        
        options = {}.tap do |options|
          options[:consistency] = thrift_write_consistency
          options[:ttl] = row_ttl unless row_ttl.nil?
        end
        connection.insert(column_family, key.to_s, attributes, options)
      end
    end
  end
end