Class: Chair
- Inherits:
-
Object
- Object
- Chair
- Defined in:
- lib/chair/chair.rb,
lib/chair/version.rb
Overview
Defined Under Namespace
Classes: Row
Constant Summary collapse
- VERSION =
"1.1.3"
Instance Attribute Summary collapse
-
#indices ⇒ Set<Symbol>
readonly
the set of indices for the table.
-
#primary_key ⇒ Symbol
readonly
the primary key of the table.
Instance Method Summary collapse
-
#add_column!(column) ⇒ Bool
Add a new column to the table.
-
#add_columns!(*columns) ⇒ Bool
Add multiple columns to the table.
-
#add_index!(column) ⇒ Symbol
Add a new index to the table.
-
#all ⇒ Array<Chair::Row>
Retrieve all rows.
-
#columns ⇒ Array<Symbol>
Retrieve the current columns Order is guaranteed to be the order that the columns were inserted in, i.e., left to right.
-
#find(pk) ⇒ Row?
(also: #[])
Finds a row by searching based on primary key.
-
#find_by(args) ⇒ Row?
Find a row based on the data given.
-
#first ⇒ Chair::Row
Retrieve the first row in the table.
-
#has_primary_key? ⇒ Bool
Does this table have a primary key?.
-
#initialize(*columns) ⇒ Chair
constructor
Creates a new Table object.
-
#insert!(args) ⇒ Row?
Insert a new row of data into the column.
- #inspect ⇒ Object
-
#last ⇒ Chair::Row
Retrieve the last row in the table.
-
#merge!(column, map, opts = {}) ⇒ Object
Merge the table with a map of primary keys to values.
-
#method_missing(method_sym, *arguments, &block) ⇒ Object
Method_missing is used to dispatch to find_by_* and where_*_is.
-
#remove_index!(column) ⇒ Symbol
Remove an index from the table.
-
#set_primary_key!(column) ⇒ Symbol?
Set the primary key of the table.
-
#size ⇒ Fixnum
(also: #count)
The number of rows in the table.
-
#table_scan(args) ⇒ Array<Row>
Scan the table to find rows.
-
#where(args) ⇒ Array<Row>?
Search for rows based on given data.
Constructor Details
#initialize(*columns) ⇒ Chair
Creates a new Table object
11 12 13 14 15 16 17 18 |
# File 'lib/chair/chair.rb', line 11 def initialize(*columns) @table = [] @columns = {} @columns_id_counter = 0 add_columns!(*columns) @primary_key = nil @indices = {} end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_sym, *arguments, &block) ⇒ Object
Method_missing is used to dispatch to find_by_* and where_*_is
106 107 108 109 110 111 112 113 114 115 |
# File 'lib/chair/chair.rb', line 106 def method_missing(method_sym, *arguments, &block) # the first argument is a Symbol, so you need to_s it if you want to pattern match if method_sym.to_s =~ /^find_by_(.*)$/ find_by($1.to_sym => arguments.first) elsif method_sym.to_s =~ /^where_(.*)_is$/ where($1.to_sym => arguments.first) else super end end |
Instance Attribute Details
#indices ⇒ Set<Symbol> (readonly)
the set of indices for the table
6 7 8 |
# File 'lib/chair/chair.rb', line 6 def indices @indices end |
#primary_key ⇒ Symbol (readonly)
the primary key of the table
6 7 8 |
# File 'lib/chair/chair.rb', line 6 def primary_key @primary_key end |
Instance Method Details
#add_column!(column) ⇒ Bool
Add a new column to the table.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/chair/chair.rb', line 24 def add_column!(column) case column when Symbol else raise ArgumentError, "Column name should be Symbol not #{column.class}" end if @columns.include? column false else @columns[column] = @columns_id_counter @columns_id_counter += 1 true end end |
#add_columns!(*columns) ⇒ Bool
Add multiple columns to the table
42 43 44 45 46 |
# File 'lib/chair/chair.rb', line 42 def add_columns!(*columns) result = true columns.each { |c| result &&= add_column!(c) } result end |
#add_index!(column) ⇒ Symbol
Add a new index to the table
59 60 61 62 63 64 65 66 67 68 |
# File 'lib/chair/chair.rb', line 59 def add_index!(column) check_column_exists(column) if @indices.include?(column) or instance_variable_defined?("@#{column}_index_map".to_sym) raise ArgumentError, "Column #{column.inspect} is already an index" end @indices[column] = "@#{column}_index_map".to_sym instance_variable_set(@indices[column], build_index(column)) column end |
#all ⇒ Array<Chair::Row>
Retrieve all rows
240 241 242 |
# File 'lib/chair/chair.rb', line 240 def all @table end |
#columns ⇒ Array<Symbol>
Retrieve the current columns Order is guaranteed to be the order that the columns were inserted in, i.e., left to right
52 53 54 |
# File 'lib/chair/chair.rb', line 52 def columns @columns.keys end |
#find(pk) ⇒ Row? Also known as: []
Finds a row by searching based on primary key
132 133 134 135 136 137 138 |
# File 'lib/chair/chair.rb', line 132 def find(pk) if has_primary_key? idx = @pk_map[pk] @table[idx] else nil end end |
#find_by(args) ⇒ Row?
Find a row based on the data given
174 175 176 |
# File 'lib/chair/chair.rb', line 174 def find_by(args) where(args).first end |
#first ⇒ Chair::Row
Retrieve the first row in the table
246 247 248 |
# File 'lib/chair/chair.rb', line 246 def first @table.first end |
#has_primary_key? ⇒ Bool
Does this table have a primary key?
203 204 205 |
# File 'lib/chair/chair.rb', line 203 def has_primary_key? not @primary_key.nil? end |
#insert!(args) ⇒ Row?
Insert a new row of data into the column
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/chair/chair.rb', line 86 def insert!(args) args = process_incoming_data(args) if has_primary_key? unless args.include? @primary_key # If our table has a primary key, but can't find it in the data raise ArgumentError, 'Missing primary key in record to be inserted' end val = args[@primary_key] if @pk_map.has_key?(val) raise RuntimeError, "Primary key #{val.inspect} already exists in table" end @pk_map[val] = @table.size end row = Row.new(self, @table.size, args) @table << row row end |
#inspect ⇒ Object
256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/chair/chair.rb', line 256 def inspect # Use the table's column list to order our columns inspection = [] inspection << "primary_key: #{@primary_key.inspect}" if has_primary_key? inspection << "indices: #{@indices.keys.inspect}" unless @indices.empty? inspection << "columns: #{@columns.keys.inspect}" unless @columns.empty? inspection = inspection.compact.join(', ') unless inspection.empty? inspection.insert 0, ' ' end "#<#{self.class}#{inspection}>" end |
#last ⇒ Chair::Row
Retrieve the last row in the table
252 253 254 |
# File 'lib/chair/chair.rb', line 252 def last @table.last end |
#merge!(column, map, opts = {}) ⇒ Object
Merge the table with a map of primary keys to values. There must be a primary key.
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/chair/chair.rb', line 212 def merge!(column, map, opts = {}) unless has_primary_key? raise 'No primary key exists for this table' end # For each key, value map.each_pair do |key, val| if @pk_map.include? key # if we do, check if the row has a value in the column row = @table[@pk_map[key]] # if it does, can we overwrite? if row.has_attribute?(column) and not opts[:overwrite] raise "Value already exists in table for primary key #{key.inspect} and column #{column.inspect}" end # if so, overwrite row[column] = val else # Check if we have the key in our pk_map. if not, if opts[:create_row] # if we can create rows, insert! @primary_key => key, column => val # create a row else raise "No such row with primary key #{key.inspect} exists" # or raise an error end end end self end |
#remove_index!(column) ⇒ Symbol
Remove an index from the table
73 74 75 76 77 78 79 80 81 |
# File 'lib/chair/chair.rb', line 73 def remove_index!(column) check_column_exists(column) unless @indices.include?(column) or instance_variable_defined?("@#{column}_index_map".to_sym) raise ArgumentError, "Column #{column} is not indexed" end ivar = @indices.delete column remove_instance_variable(ivar) unless ivar.nil? column end |
#set_primary_key!(column) ⇒ Symbol?
Set the primary key of the table.
192 193 194 195 196 197 198 199 |
# File 'lib/chair/chair.rb', line 192 def set_primary_key!(column) unless has_primary_key? check_column_exists column remove_index!(column) if indices.include? column @pk_map = build_pk_map column @primary_key = column end end |
#size ⇒ Fixnum Also known as: count
The number of rows in the table
119 120 121 |
# File 'lib/chair/chair.rb', line 119 def size @table.size end |
#table_scan(args) ⇒ Array<Row>
Scan the table to find rows
181 182 183 184 185 186 187 |
# File 'lib/chair/chair.rb', line 181 def table_scan(args) results = @table.to_set args.each_pair do |col, value| results = restrict_with_table_scan(col, value, results) end results.to_a end |
#where(args) ⇒ Array<Row>?
Search for rows based on given data
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/chair/chair.rb', line 144 def where(args) # Try and find a primary key if has_primary_key? and args.keys.include? @primary_key idx = @pk_map[args[@primary_key]] return [@table[idx]] end indexed_cols = find_valid_indices(args.keys) results = @table.to_set # First restrict the query as far as we can with indices unless indexed_cols.empty? indexed_cols.each do |col| results = restrict_with_index(col, args[col], results) end end # Then, perform table scans for the rest of the restrictions # Removed the indexed columns args = args.reject { |col, val| indexed_cols.include? col } #slow O(N) find args.each_pair do |col, val| results = restrict_with_table_scan(col, val, results) end results.to_a end |