Class: Palsy::Map

Inherits:
Set show all
Defined in:
lib/palsy/basic/map.rb

Overview

Palsy::Map is an emulation of Ruby’s Hash class, where objects are unordered and unique by the keyed value. They are a Palsy::Set and Palsy::Collection and have Enumerable support. Take a look at Palsy::Object which is similar but semantically different in a few ways.

Palsy::Map keys and values must be marshallable, and their uniqueness for sanity’s sake must also be enforced in their marshalled output.

Here’s an example:

obj = Palsy::Map.new("some_maps", "a_specific_map")
obj[1] = 2
obj[1] == 2 #=> true

This will create a table called “some_maps” and all i/o will be directed to that table with an additional key of “a_specific_map”. This allows you to coordinate multiple maps in a single table.

Another example:

obj1 = Palsy::Map.new("some_maps", "a_specific_map")
obj2 = Palsy::Map.new("some_maps", "a_specific_map")
obj3 = Palsy::Map.new("some_maps", "a_different_map")

obj1 == obj2 #=> true
obj1[1] = 2
obj2[1] == 2 #=> also true
obj3 == obj1 #=> false (different map keys)
obj3[1] = 3
obj2[1] == 3 #=> also false

Instance Attribute Summary

Attributes inherited from Generic

#db, #object_name, #table_name

Instance Method Summary collapse

Methods inherited from Set

#add, #clear, #delete, #has_key?, #keys

Methods inherited from Collection

#initialize

Methods inherited from Generic

#==, #_dump, _load, #initialize, #post_marshal_init

Constructor Details

This class inherits a constructor from Palsy::Collection

Instance Method Details

#[](key) ⇒ Object

Obtain the value for a given key. Returns nil if the key does not have an entry.



42
43
44
45
# File 'lib/palsy/basic/map.rb', line 42

def [](key)
  value = @db.execute_t("select value from #{@table_name} where name=? and key=?", [@object_name, Marshal.dump(key)]).first.first rescue nil
  return value && Marshal.load(value)
end

#[]=(key, value) ⇒ Object

Associate a value with a given key. Keys will be deleted from the database before attempting to write the new pair.



51
52
53
54
55
56
57
# File 'lib/palsy/basic/map.rb', line 51

def []=(key, value)
  @db.with_t do
    delete(key)
    @db.execute_t("insert into #{@table_name} (name, key, value) values (?, ?, ?)", [@object_name, Marshal.dump(key), Marshal.dump(value)])
  end
  value
end

#create_tableObject

Defines the schema for Maps.



97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/palsy/basic/map.rb', line 97

def create_table
  @db.execute_t <<-EOF
    create table if not exists #{@table_name} (
      id integer not null primary key autoincrement,
      name varchar(255) not null,
      key varchar(255) not null,
      value text not null,
      UNIQUE(name, key)
    )
  EOF

  @db.execute_t "create index if not exists #{@table_name}_name_idx on #{@table_name} (name)"
end

#eachObject

Successively yields key and value for each item in the map. Modifications to either the key or value yielded will not persist.



78
79
80
81
82
83
84
# File 'lib/palsy/basic/map.rb', line 78

def each
  @db.with_t do
    keys.each do |key|
      yield key, self[key]
    end
  end
end

#replace(hash) ⇒ Object

replace this map with the contents of a Hash.



62
63
64
65
66
67
68
69
70
71
72
# File 'lib/palsy/basic/map.rb', line 62

def replace(hash)
  @db.with_t do
    clear

    return if hash.keys.empty?

    value_string = ("(?, ?, ?)," * hash.keys.count).chop

    @db.execute_t("insert into #{@table_name} (name, key, value) values #{value_string}", hash.map { |key, value| [@object_name, Marshal.dump(key), Marshal.dump(value)] }.flatten)
  end
end

#to_hashObject

Convert this map to a Ruby Hash object.



89
90
91
92
# File 'lib/palsy/basic/map.rb', line 89

def to_hash
  rows = @db.execute_t("select key, value from #{@table_name} where name=?", [@object_name])
  Hash[rows.map { |x| x.map { |y| Marshal.load(y) } }]
end