Class: Mongify::Database::Column
- Inherits:
-
Object
- Object
- Mongify::Database::Column
- Defined in:
- lib/mongify/database/column.rb
Overview
A column that is used to access sql data and transform it into the no sql database
Structure
Structure for defining a column is as follows:
column "name", :type, {options}
Columns with no type given will be set to :string
Notes
Leaving a column out when defining a table will result in a copy of the information (as a string).
Types
Types of columns are supported:
:key # Columns that are primary keys need to be marked as :key type
:integer # Will be converted to a integer
:float # Will be converted to a float
:decimal # Will be converted to a string *(you can change default behaviour read below)
:string # Will be converted to a string
:text # Will be converted to a string
:datetime # Will be converted to a Time format (DateTime is not currently supported in the Mongo ruby driver)
:date # Will be converted to a Time format (Date is not currently supported in the Mongo ruby driver)
:timestamps # Will be converted to a Time format
:time # Will be converted to a Time format (the date portion of the Time object will be 2000-01-01)
:binary # Will be converted to a string
:boolean # Will be converted to a true or false values
Options
column "post_id", :integer, :referneces => :posts # Referenced columns need to be marked as such, this will mean that they will be updated
# with the new BSON::ObjectID.
NOTE: if you rename the table ‘posts’, you should set the :references to the new name
column "name", :string, :ignore => true # Ignoring a column will make the column NOT copy over to the new database
column "surname", :string, :rename_to => 'last_name'# Rename_to allows you to rename the column
column "post_id", :integer, :auto_detect => true # Will run auto detect and make this column a :references => 'posts', :on => 'post_id' for you
# More used when reading a sql database, NOT recommended for use during processing of translation
For decimal columns you can specify a few options:
column "total", # This is a default conversion setting.
:decimal,
:as => 'string'
column "total", # You can specify to convert your decimal to integer
:decimal, # specifying scale will define how many decimal places to keep
:as => 'integer', # Example: :scale => 2 will convert 123.4567 to 12346 in to mongodb
:scale => 2
Decimal Storage
Unfortunately MongoDB Ruby Drivers doesn’t support BigDecimal, so to ensure all data is stored correctly (without losing information) I’ve chosen to store as String, however you can overwrite this functionality in one of two ways: The reason you would want to do this, is to make this searchable via a query.
1) You can specify :as => ‘integer’, :scale => 2
column "total", :decimal, :as => 'integer', :scale => 2
#It would take a value of 123.456 and store it as an integer of value 12346
<b>2) You can specify your own custom conversion by doing a Table#before_save
Example:
table "invoice" do
column "name", :string
column "total", :decimal
before_save do |row|
row.total = (BigDecimal.new(row.total) * 1000).round
end
end
This would take 123.456789 in the total column and convert it to an interger of value 123457 (and in your app you can convert it back to a decimal)
REMEMBER there is a limit on how big of an integer you can store in BSON/MongoDB (bsonspec.org/#/specification)
Constant Summary collapse
- AVAILABLE_OPTIONS =
List of available options for a column
['references', 'ignore', 'rename_to', 'as', 'scale']
Instance Attribute Summary collapse
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#sql_name ⇒ Object
readonly
Returns the value of attribute sql_name.
-
#type ⇒ Object
Returns the value of attribute type.
Class Method Summary collapse
-
.auto_detect(column) ⇒ Object
Auto detects if a column is an :key column or is a reference column.
Instance Method Summary collapse
-
#as ⇒ String
Used when trying to figure out how to convert a decimal value.
-
#as=(value) ⇒ Object
Sets option to either ‘string’ or ‘integer’, defults to ‘string’ for unknown values.
-
#as_integer? ⇒ Boolean
Returns true if :as was passed as integer.
-
#auto_detect? ⇒ Boolean
Returns true if column should be auto_detected (passed via options).
-
#ignored? ⇒ Boolean
Returns true if column is ignored.
-
#initialize(sql_name, type = :string, options = {}) ⇒ Column
constructor
A new instance of Column.
-
#key? ⇒ Boolean
Returns true if column is a :key type column.
-
#method_missing(meth, *args, &blk) ⇒ Object
Sets up a accessor method for an option.
-
#name ⇒ Object
Returns the no_sql record name.
-
#referenced? ⇒ Boolean
Returns true if the column is a reference column.
-
#renamed? ⇒ Boolean
Returns true if column is being renamed.
-
#scale ⇒ integer
Get the scale option for decimal to integer conversion column ‘total’, :decimal, :as => ‘integer’, :scale => 3.
-
#scale=(value) ⇒ Object
Set the scale option for decimal to integer conversion column ‘total’, :decimal, :as => ‘integer’, :scale => 3.
-
#to_print ⇒ Object
(also: #to_s)
Returns a string representation of the column as it would show in a translation file.
-
#translate(value) ⇒ Object
Returns a translated hash from a given value Example: @column = Column.new(“surname”, :string, :rename_to => ‘last_name’) @column.translate(“Smith”) # => => “Smith”.
Constructor Details
#initialize(sql_name, type = :string, options = {}) ⇒ Column
Returns a new instance of Column.
95 96 97 98 99 100 101 102 103 104 |
# File 'lib/mongify/database/column.rb', line 95 def initialize(sql_name, type=:string, ={}) @sql_name = sql_name , type = type, nil if type.is_a?(Hash) self.type = type @options = .stringify_keys @auto_detect = @options.delete('auto_detect') run_auto_detect! self end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args, &blk) ⇒ Object
Sets up a accessor method for an option
def rename_to=(value)
['rename_to'] = value
end
def rename_to
['rename_to']
end
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/mongify/database/column.rb', line 149 def method_missing(meth, *args, &blk) method_name = meth.to_s.gsub("=", '') if AVAILABLE_OPTIONS.include?(method_name) unless self.class.method_defined?(method_name.to_sym) class_eval <<-EOF def #{method_name}=(value) options['#{method_name}'] = value end EOF end unless self.class.method_defined?("#{method_name}=".to_sym) class_eval <<-EOF def #{method_name} options['#{method_name}'] end EOF end send(meth, *args, &blk) else super(meth, *args, &blk) end end |
Instance Attribute Details
#options ⇒ Object (readonly)
Returns the value of attribute options.
80 81 82 |
# File 'lib/mongify/database/column.rb', line 80 def @options end |
#sql_name ⇒ Object (readonly)
Returns the value of attribute sql_name.
80 81 82 |
# File 'lib/mongify/database/column.rb', line 80 def sql_name @sql_name end |
#type ⇒ Object
Returns the value of attribute type.
80 81 82 |
# File 'lib/mongify/database/column.rb', line 80 def type @type end |
Class Method Details
.auto_detect(column) ⇒ Object
Auto detects if a column is an :key column or is a reference column
86 87 88 89 90 91 92 93 |
# File 'lib/mongify/database/column.rb', line 86 def self.auto_detect(column) case column.sql_name.downcase when 'id' column.type = :key if column.type == :integer when /(.*)_id/ column.references = $1.to_s.pluralize unless column.referenced? || column.type != :integer end end |
Instance Method Details
#as ⇒ String
Used when trying to figure out how to convert a decimal value
199 200 201 |
# File 'lib/mongify/database/column.rb', line 199 def as ['as'] ||= 'string' end |
#as=(value) ⇒ Object
Sets option to either ‘string’ or ‘integer’, defults to ‘string’ for unknown values
204 205 206 207 |
# File 'lib/mongify/database/column.rb', line 204 def as=(value) value = value.to_s.downcase ['as'] = ['string', 'integer'].include?(value) ? value : 'string' end |
#as_integer? ⇒ Boolean
Returns true if :as was passed as integer
209 210 211 |
# File 'lib/mongify/database/column.rb', line 209 def as_integer? self.as == 'integer' end |
#auto_detect? ⇒ Boolean
Returns true if column should be auto_detected (passed via options)
188 189 190 |
# File 'lib/mongify/database/column.rb', line 188 def auto_detect? !!@auto_detect end |
#ignored? ⇒ Boolean
Returns true if column is ignored
193 194 195 |
# File 'lib/mongify/database/column.rb', line 193 def ignored? !!self.ignore end |
#key? ⇒ Boolean
Returns true if column is a :key type column
183 184 185 |
# File 'lib/mongify/database/column.rb', line 183 def key? self.type == :key end |
#name ⇒ Object
Returns the no_sql record name
113 114 115 |
# File 'lib/mongify/database/column.rb', line 113 def name @name ||= rename_to || sql_name end |
#referenced? ⇒ Boolean
Returns true if the column is a reference column
173 174 175 |
# File 'lib/mongify/database/column.rb', line 173 def referenced? !self.['references'].nil? end |
#renamed? ⇒ Boolean
Returns true if column is being renamed
178 179 180 |
# File 'lib/mongify/database/column.rb', line 178 def renamed? self.name != self.sql_name end |
#scale ⇒ integer
Get the scale option for decimal to integer conversion
column 'total', :decimal, :as => 'integer', :scale => 3
216 217 218 |
# File 'lib/mongify/database/column.rb', line 216 def scale ['scale'] ||= 0 end |
#scale=(value) ⇒ Object
Set the scale option for decimal to integer conversion
column 'total', :decimal, :as => 'integer', :scale => 3
222 223 224 |
# File 'lib/mongify/database/column.rb', line 222 def scale=(value) ['scale'] = value.to_i end |
#to_print ⇒ Object Also known as: to_s
Returns a string representation of the column as it would show in a translation file. Mainly used during print out of translation file
133 134 135 136 137 138 |
# File 'lib/mongify/database/column.rb', line 133 def to_print "column \"#{sql_name}\", :#{type}".tap do |output| = .map{|k, v| (v == nil) ? nil : ":#{k} => \"#{v}\""}.compact output << ", #{.join(', ')}" unless .blank? end end |
#translate(value) ⇒ Object
121 122 123 124 125 126 127 128 129 |
# File 'lib/mongify/database/column.rb', line 121 def translate(value) return {} if ignored? case type when :key {"pre_mongified_id" => value.to_i} else {"#{self.name}" => type_cast(value)} end end |