Module: Foobara::Persistence

Defined in:
foobara-0.0.110/projects/persistence/src/entity_attributes_crud_driver.rb,
foobara-0.0.110/projects/persistence/src/entity_base.rb,
foobara-0.0.110/projects/persistence/src/persistence.rb,
foobara-0.0.110/projects/persistence/src/entity_base/table.rb,
foobara-0.0.110/projects/in_memory_crud_driver/src/in_memory.rb,
foobara-0.0.110/projects/persistence/lib/foobara/persistence.rb,
foobara-0.0.110/projects/persistence/src/entity_base/transaction.rb,
foobara-0.0.110/projects/persistence/src/entity_base/transaction_table.rb,
foobara-0.0.110/projects/in_memory_crud_driver_minimal/src/in_memory_minimal.rb,
foobara-0.0.110/projects/persistence/src/entity_base/transaction/state_machine.rb,
foobara-0.0.110/projects/persistence/src/entity_base/transaction_table/concerns/queries.rb,
foobara-0.0.110/projects/persistence/src/entity_base/transaction/concerns/state_transitions.rb,
foobara-0.0.110/projects/persistence/src/entity_base/transaction/concerns/transaction_tracking.rb,
foobara-0.0.110/projects/persistence/src/entity_base/transaction_table/concerns/record_tracking.rb,
foobara-0.0.110/projects/persistence/src/entity_base/transaction/concerns/entity_callback_handling.rb

Overview

Might be best to rename this to CrudDrivers or CrudDriver instead of Persistence?

Defined Under Namespace

Modules: CrudDrivers Classes: EntityAttributesCrudDriver, EntityBase, InvalidRecordError, NoTableOrCrudDriverError, NoTransactionOpenError

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.default_crud_driverObject

Returns the value of attribute default_crud_driver.



7
8
9
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 7

def default_crud_driver
  @default_crud_driver
end

Class Method Details

.base_for_entity_class(entity_class) ⇒ Object



134
135
136
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 134

def base_for_entity_class(entity_class)
  table_for_entity_class_name(entity_class.full_entity_name).entity_base
end

.base_for_entity_class_name(entity_class_name) ⇒ Object



130
131
132
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 130

def base_for_entity_class_name(entity_class_name)
  table_for_entity_class_name(entity_class_name).entity_base
end

.basesObject



126
127
128
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 126

def bases
  @bases ||= {}
end

.current_transaction(object) ⇒ Object

TODO: support transactions across multiple bases



53
54
55
56
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 53

def current_transaction(object)
  base = to_base(object)
  base.current_transaction
end

.current_transaction!(object) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 58

def current_transaction!(object)
  base = to_base(object)
  tx = base.current_transaction

  unless tx
    # :nocov:
    raise NoTransactionOpenError
    # :nocov:
  end

  tx
end

.current_transaction_table(object) ⇒ Object



75
76
77
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 75

def current_transaction_table(object)
  current_transaction(object).table_for(object)
end

.current_transaction_table!(object) ⇒ Object



71
72
73
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 71

def current_transaction_table!(object)
  current_transaction!(object).table_for(object)
end

.default_baseObject



19
20
21
22
23
24
25
26
27
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 19

def default_base
  @default_base ||= if default_crud_driver
                      base = EntityBase.new(
                        "default_entity_base",
                        entity_attributes_crud_driver: default_crud_driver
                      )
                      register_base(base)
                    end
end

.install!Object



16
17
18
19
# File 'foobara-0.0.110/projects/persistence/lib/foobara/persistence.rb', line 16

def install!
  EntityBase::Transaction::Concerns::EntityCallbackHandling.install!
  EntityBase::Transaction.install!
end

.object_to_base(object) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 107

def object_to_base(object)
  case object
  when EntityBase
    object
  when ::String
    bases[object]
  when ::Symbol
    bases[object.to_s]
  when Class
    base_for_entity_class(object)
  when Entity
    base_for_entity_class(object.class)
  else
    # :nocov:
    raise ArgumentError, "Not able to convert #{object} to an entity base"
    # :nocov:
  end
end

.objects_to_bases(objects) ⇒ Object



101
102
103
104
105
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 101

def objects_to_bases(objects)
  objects.map do |object|
    object_to_base(object)
  end.uniq
end

.register_base(base) ⇒ Object



155
156
157
158
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 155

def register_base(base)
  # TODO: add some validations here
  bases[base.name] = base
end

.register_entity(base, entity_class, table_name: entity_class.full_entity_name) ⇒ Object



160
161
162
163
164
165
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 160

def register_entity(base, entity_class, table_name: entity_class.full_entity_name)
  base = to_base(base)

  table = base.register_entity_class(entity_class, table_name:)
  tables_for_entity_class_name[entity_class.full_entity_name] = table
end

.reset_allObject



4
5
6
7
8
9
10
11
12
13
14
# File 'foobara-0.0.110/projects/persistence/lib/foobara/persistence.rb', line 4

def reset_all
  @tables_for_entity_class_name = @bases = @default_crud_driver = @default_base = nil
  EntityBase::Transaction::Concerns::EntityCallbackHandling.reset_all
  EntityBase::Transaction.reset_all

  Util.descendants(Foobara::Entity).each do |entity_class|
    if entity_class.instance_variable_defined?(:@entity_base)
      entity_class.remove_instance_variable(:@entity_base)
    end
  end
end

.table_for_entity_class_name(entity_class_name) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 138

def table_for_entity_class_name(entity_class_name)
  table = tables_for_entity_class_name[entity_class_name]

  return table if table

  if default_base
    table = EntityBase::Table.new(entity_class_name, default_base)
    default_base.register_table(table)
    tables_for_entity_class_name[entity_class_name] = table
  else
    # :nocov:
    raise NoTableOrCrudDriverError,
          "Can't find table for #{entity_class_name} and can't dynamically build one without default crud driver."
    # :nocov:
  end
end

.tables_for_entity_class_nameObject



167
168
169
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 167

def tables_for_entity_class_name
  @tables_for_entity_class_name ||= {}
end

.to_base(object) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 79

def to_base(object)
  bases = to_bases(object)

  if bases.empty?
    # :nocov:
    raise "Could not find a base for #{object}"
    # :nocov:
  end

  if bases.size > 1
    # :nocov:
    raise "Expected to only find 1 base for #{object} but found #{bases.size}"
    # :nocov:
  end

  bases.first
end

.to_bases(object) ⇒ Object



97
98
99
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 97

def to_bases(object)
  objects_to_bases(Util.array(object))
end

.transaction(*objects, mode: nil, &block) ⇒ Object

TODO: automatically order these by dependency… TODO: also, consider automatically opening transactions for dependent entities automatically…



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'foobara-0.0.110/projects/persistence/src/persistence.rb', line 31

def transaction(*objects, mode: nil, &block)
  # def transaction(mode = nil, existing_transaction: nil)
  bases = objects_to_bases(objects)

  if bases.empty?
    # :nocov:
    raise "No bases found for #{objects}"
    # :nocov:
  end

  if bases.size == 1
    bases.first.transaction(mode, &block)
  else
    bases.inject(block) do |nested_proc, base|
      proc do
        base.transaction(mode, &nested_proc)
      end
    end.call
  end
end