Class: Heresy::Model
- Inherits:
-
Object
- Object
- Heresy::Model
- Defined in:
- lib/heresy/model.rb
Overview
This class is responsible for storing and retrieving the model data in a schema-free manner.
Class Attribute Summary collapse
-
.db ⇒ Object
Reference to the Sequel DB object.
-
.formatter ⇒ Object
The formatter is what converts the assembled model hash data into the string that gets saved in the database.
-
.schema(table_name = name.demodulize.underscore.pluralize) {|@schema| ... } ⇒ Object
Accesses the database schema for this model.
Instance Attribute Summary collapse
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#updated_at ⇒ Object
readonly
Returns the value of attribute updated_at.
Class Method Summary collapse
-
.body_fields ⇒ Object
This is a hash of all specified fields and their type converters.
-
.dataset ⇒ Object
Reference to the Sequel dataset for this model’s table.
-
.fields {|Schema::Fields.new(self)| ... } ⇒ Object
Yields a Schema::Fields object for specifying fields for this model.
-
.find(uuid) ⇒ Object
Finds a single or an array of entries by UUID.
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#initialize(attributes = {}) ⇒ Model
constructor
A new instance of Model.
- #inspect ⇒ Object
- #new? ⇒ Boolean
-
#reload ⇒ Object
Reloads a model’s data from the database using the existing UUID.
- #retrieve(row) ⇒ Object
-
#save ⇒ Object
Saves the record in the database.
- #uuid ⇒ Object
Constructor Details
#initialize(attributes = {}) ⇒ Model
Returns a new instance of Model.
114 115 116 |
# File 'lib/heresy/model.rb', line 114 def initialize(attributes = {}) set_attributes attributes end |
Class Attribute Details
.db ⇒ Object
Reference to the Sequel DB object
75 76 77 |
# File 'lib/heresy/model.rb', line 75 def db @db = Heresy.db end |
.formatter ⇒ Object
The formatter is what converts the assembled model hash data into the string that gets saved in the database. The default formatter stores zlib compressed JSON hashes.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/heresy/model.rb', line 87 def formatter @formatter ||= \ if superclass.respond_to?(:formatter) superclass.formatter else :json end if @formatter.is_a?(Symbol) require "heresy/formatting/#{@formatter}" @formatter = Heresy::Formatting.const_get(@formatter.to_s.capitalize) end @formatter end |
.schema(table_name = name.demodulize.underscore.pluralize) {|@schema| ... } ⇒ Object
Accesses the database schema for this model. The basic schema will look something like this:
create_table :entries do |t|
t.primary_key :id, :int
t.column :uuid, :binary
t.column :updated_at, :timestamp
t.column :body, :blob
end
You can modify any of those from the schema directly.
class Entry < Heresy::Model
schema :custom_table_name do |s|
s.id.type = :medium_int
s.id.[:size] = 11
s.body.type = :medium_blob
end
end
The types are any valid type from the Sequel ruby library. There are a few convenience types, however. (See Heresy::Schema::Column)
All models have the same 4 database fields:
- an auto-incremented ID and updated_at timestamp
- a 32 character hex UUID that gets stored as a 16 character binary string. This is how items are retrieved.
- a BLOB body character for storing the model's data.
34 35 36 37 38 |
# File 'lib/heresy/model.rb', line 34 def schema(table_name = name.demodulize.underscore.pluralize) @schema ||= Heresy::Schema.new(db, table_name.to_sym) yield @schema if block_given? @schema end |
Instance Attribute Details
#id ⇒ Object (readonly)
Returns the value of attribute id.
111 112 113 |
# File 'lib/heresy/model.rb', line 111 def id @id end |
#updated_at ⇒ Object (readonly)
Returns the value of attribute updated_at.
112 113 114 |
# File 'lib/heresy/model.rb', line 112 def updated_at @updated_at end |
Class Method Details
.body_fields ⇒ Object
This is a hash of all specified fields and their type converters. If a type converter is set (see #fields), values are parsed in the field attribute writers, and encoded when saving to the database.
60 61 62 |
# File 'lib/heresy/model.rb', line 60 def body_fields @body_fields ||= {} end |
.dataset ⇒ Object
Reference to the Sequel dataset for this model’s table.
80 81 82 |
# File 'lib/heresy/model.rb', line 80 def dataset @dataset ||= db[schema.name] end |
.fields {|Schema::Fields.new(self)| ... } ⇒ Object
Yields a Schema::Fields object for specifying fields for this model. These fields get assembled into a hash and stored in the BODY attribute of the schema.
By default, fields are all strings. Other types such as integers and dates can be specified for automatic conversions.
class Entry < Heresy::Model
fields do |f|
f.string :title
f.integer :comments_count
f.datetime :published_at
end
end
54 55 56 |
# File 'lib/heresy/model.rb', line 54 def fields yield Schema::Fields.new(self) end |
.find(uuid) ⇒ Object
Finds a single or an array of entries by UUID.
65 66 67 68 69 70 71 72 |
# File 'lib/heresy/model.rb', line 65 def find(uuid) if uuid.is_a?(Array) rows = dataset.filter(:uuid => uuid.map { |u| u.to_a.pack("H*") }).to_a rows.map! { |row| retrieve(row) } else new(:uuid => uuid).reload end end |
Instance Method Details
#==(other) ⇒ Object
143 144 145 |
# File 'lib/heresy/model.rb', line 143 def ==(other) other.class == self.class && other.uuid == uuid end |
#inspect ⇒ Object
147 148 149 |
# File 'lib/heresy/model.rb', line 147 def inspect "<#{self.class.name} (#{uuid}) #{self.class.body_fields.keys.map { |k| "@#{k}=#{send(k).inspect}" } * ', '}>" end |
#new? ⇒ Boolean
134 135 136 |
# File 'lib/heresy/model.rb', line 134 def new? @id.nil? end |
#reload ⇒ Object
Reloads a model’s data from the database using the existing UUID.
139 140 141 |
# File 'lib/heresy/model.rb', line 139 def reload retrieve(rowset.select(:id, :body, :updated_at).first) end |
#retrieve(row) ⇒ Object
151 152 153 154 155 156 |
# File 'lib/heresy/model.rb', line 151 def retrieve(row) @id = row[:id] @updated_at = row[:updated_at] set_attributes self.class.formatter.decode(row[:body]) self end |
#save ⇒ Object
Saves the record in the database.
123 124 125 126 127 128 129 130 131 132 |
# File 'lib/heresy/model.rb', line 123 def save if new? self.class.dataset << {:uuid => uuid.to_a.pack("H*"), :body => self.class.formatter.encode(assemble_body)} reload else rowset.update({:updated_at => nil}) reload end true end |
#uuid ⇒ Object
118 119 120 |
# File 'lib/heresy/model.rb', line 118 def uuid @uuid ||= UUID.generate(:compact) end |