Class: DbMemoize::Value
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- DbMemoize::Value
- Defined in:
- lib/db_memoize/value.rb
Constant Summary collapse
- SQL =
::Simple::SQL
- ALL_COLUMNS =
[ :val_string, :val_integer, :val_float, :val_time, :val_object, :val_boolean, :val_nil ].freeze
Class Method Summary collapse
- .ar_create_value(column, entity_table_name:, entity_id:, method_name:, value:) ⇒ Object
- .delete_all_ordered ⇒ Object
- .fast_create(entity_table_name, entity_id, method_name, value) ⇒ Object
- .simple_sql_create_value(column, entity_table_name:, entity_id:, method_name:, value:) ⇒ Object
Instance Method Summary collapse
Class Method Details
.ar_create_value(column, entity_table_name:, entity_id:, method_name:, value:) ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/db_memoize/value.rb', line 110 def self.ar_create_value(column, entity_table_name:, entity_id:, method_name:, value:) # [TODO] this code is not resolving conflicts on the unique index. data = { :entity_table_name => entity_table_name, :entity_id => entity_id, :method_name => method_name, column => value } create!(data) end |
.delete_all_ordered ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/db_memoize/value.rb', line 32 def self.delete_all_ordered relation = self relation = all unless is_a?(ActiveRecord::Relation) sql = relation.select(:ctid).to_sql SQL.ask " DO $$DECLARE c record;\n BEGIN\n FOR c IN \#{sql} ORDER BY ctid LOOP\n DELETE FROM \#{DbMemoize::Value.table_name} WHERE ctid = c.ctid;\n END LOOP;\n END$$;\n SQL\nend\n" |
.fast_create(entity_table_name, entity_id, method_name, value) ⇒ Object
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 78 79 80 81 82 |
# File 'lib/db_memoize/value.rb', line 47 def self.fast_create(entity_table_name, entity_id, method_name, value) method_name = method_name.to_s # clear out old entry (if any). This makes sure that any existing value # is cleared out properly. SQL.ask "DELETE FROM #{table_name} WHERE(entity_table_name, entity_id, method_name) = ($1, $2, $3)", entity_table_name, entity_id, method_name column = case value when String then :val_string when Integer then :val_integer when Float then :val_float when Time then :val_time when false then :val_boolean when true then :val_boolean when nil then :val_nil when Hash then :val_object when Array then :val_object else raise "Unsupported value of type #{value.class.name}: #{value.inspect}" end value = JSON.generate(value) if column == :val_object # it looks like Simple::SQL somehow drops subsecond resolutions from # time objects. AR does not, though. So, for time values, we use the # ActiveRecord method; for everything else we use Simple::SQL (for # performance reasons: it is 10 times as fast.) if column != :val_time simple_sql_create_value column, entity_table_name: entity_table_name, entity_id: entity_id, method_name: method_name, value: value else ar_create_value column, entity_table_name: entity_table_name, entity_id: entity_id, method_name: method_name, value: value end end |
.simple_sql_create_value(column, entity_table_name:, entity_id:, method_name:, value:) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/db_memoize/value.rb', line 94 def self.simple_sql_create_value(column, entity_table_name:, entity_id:, method_name:, value:) other_columns = ALL_COLUMNS - [column] default_updates = other_columns.map { |c| "#{c}=NULL" } sql = " INSERT INTO \#{table_name}\n (entity_table_name, entity_id, method_name, \#{column}, created_at)\n VALUES($1,$2,$3,$4,NOW())\n ON CONFLICT (entity_id, entity_table_name, method_name)\n DO UPDATE\n SET \#{default_updates.join(', ')}, \#{column}=$4, created_at=NOW()\n SQL\n\n SQL.ask sql, entity_table_name, entity_id, method_name, value\nend\n".freeze |
Instance Method Details
#value ⇒ Object
27 28 29 30 |
# File 'lib/db_memoize/value.rb', line 27 def value # Note: val_boolean should come last. val_string || val_integer || val_float || val_time || val_object || val_boolean end |
#value=(value) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/db_memoize/value.rb', line 12 def value=(value) self.val_integer = self.val_float = self.val_string = self.val_boolean = self.val_time = nil case value when String then self.val_string = value when Integer then self.val_integer = value when Float then self.val_float = value when Time then self.val_time = value when false then self.val_boolean = value when true then self.val_boolean = value when nil then :nop else raise "Unsupported type #{value.class.name.inspect}, for DbMemoize" end end |