Module: Shameless::Model

Defined in:
lib/shameless/model.rb

Defined Under Namespace

Modules: InstanceMethods

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#storeObject (readonly)

Returns the value of attribute store.



7
8
9
# File 'lib/shameless/model.rb', line 7

def store
  @store
end

Instance Method Details

#attach_to(store, name) ⇒ Object



9
10
11
12
13
14
15
16
# File 'lib/shameless/model.rb', line 9

def attach_to(store, name)
  @store = store
  @name = name || self.name.downcase # TODO use activesupport?
  @cell_names = []
  cell(Cell::BASE)

  include(InstanceMethods)
end

#cell(name) ⇒ Object



26
27
28
29
30
31
# File 'lib/shameless/model.rb', line 26

def cell(name)
  name = name.to_s
  @cell_names << name

  define_method(name) { @cells[name] }
end

#create_tables!Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/shameless/model.rb', line 89

def create_tables!
  @store.create_table!(table_name) do |t, sharded_table_name|
    t.primary_key :id
    t.varchar :uuid, size: 36
    t.varchar :column_name, null: false
    t.integer :ref_key, null: false
    t.mediumblob :body

    created_at_type = @store.configuration.legacy_created_at_is_bigint ? :bigint : :datetime
    t.column :created_at, created_at_type, null: false

    t.index %i[uuid column_name ref_key], name: "#{sharded_table_name}_model", unique: true
  end

  @indices.each(&:create_tables!)
end

#fetch_cell(shardable_value, uuid, cell_name, ref_key) ⇒ Object



61
62
63
64
65
66
# File 'lib/shameless/model.rb', line 61

def fetch_cell(shardable_value, uuid, cell_name, ref_key)
  query = {uuid: uuid, column_name: cell_name}
  query[:ref_key] = ref_key if ref_key

  @store.where(table_name, shardable_value, query).order(:ref_key).last
end

#fetch_latest_cells(shard:, cursor:, limit:) ⇒ Object



68
69
70
71
72
73
74
75
# File 'lib/shameless/model.rb', line 68

def fetch_latest_cells(shard:, cursor:, limit:)
  query = Sequel.lit("id > ?", cursor)
  @store.where(table_name, shard, query).limit(limit).map do |cell_values|
    model = new(cell_values[:uuid])
    name = cell_values[:column_name].to_sym
    Cell.new(model, name, cell_values)
  end
end

#index(name = nil, &block) ⇒ Object



18
19
20
21
22
23
24
# File 'lib/shameless/model.rb', line 18

def index(name = nil, &block)
  @indices ||= []
  index = Index.new(name, self, &block)
  @indices << index

  define_singleton_method(index.full_name) { index }
end

#initialize_cells(instance, base_body) ⇒ Object



33
34
35
36
37
38
# File 'lib/shameless/model.rb', line 33

def initialize_cells(instance, base_body)
  Hash[@cell_names.map do |name|
    cell = name == Cell::BASE ? Cell.base(instance, base_body) : Cell.new(instance, name)
    [name, cell]
  end]
end

#max_id_on_shard(shard) ⇒ Object



77
78
79
# File 'lib/shameless/model.rb', line 77

def max_id_on_shard(shard)
  @store.find_table(table_name, shard).max(:id)
end

#prevent_readonly_attribute_mutation!(key) ⇒ Object



114
115
116
# File 'lib/shameless/model.rb', line 114

def prevent_readonly_attribute_mutation!(key)
  @indices.each {|i| i.prevent_readonly_attribute_mutation!(key) }
end

#put(values) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/shameless/model.rb', line 40

def put(values)
  if model = where(values).first
    model_values = reject_index_values(values)
    model.update(model_values)
    model
  else
    uuid = SecureRandom.uuid

    new(uuid, values).tap do |m|
      m.save

      index_values = values.merge(uuid: uuid)
      @indices.each {|i| i.put(index_values) }
    end
  end
end

#put_cell(shardable_value, cell_values) ⇒ Object



57
58
59
# File 'lib/shameless/model.rb', line 57

def put_cell(shardable_value, cell_values)
  @store.put(table_name, shardable_value, cell_values)
end

#reject_index_values(values) ⇒ Object



110
111
112
# File 'lib/shameless/model.rb', line 110

def reject_index_values(values)
  values.reject {|k, _| @indices.any? {|i| i.column?(k) } }
end

#table_nameObject



81
82
83
# File 'lib/shameless/model.rb', line 81

def table_name
  [@store.name, @name].compact.join('_')
end

#table_namesObject



85
86
87
# File 'lib/shameless/model.rb', line 85

def table_names
  [table_name, *@indices.map(&:table_name)]
end

#where(query, &block) ⇒ Object



106
107
108
# File 'lib/shameless/model.rb', line 106

def where(query, &block)
  primary_index.where(query, &block)
end