Class: Palsy::Set

Inherits:
Collection show all
Defined in:
lib/palsy/basic/set.rb

Overview

Palsy::Set is an emulation of Ruby’s Set class, where items are unordered and unique.

Sets depend heavily on Marshal and so does their uniqueness. It’s your job to ensure you’re dealing with types that are easily marshalled.

Palsy::Set is a Palsy::Collection and provides #to_set by way of Ruby’s Enumerable and Set libraries.

Here’s an example:

obj = Palsy::Set.new("some_sets", "a_specific_set")
obj.add 2
obj.include? 2 #=> true

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

Another example:

obj1 = Palsy::Set.new("some_sets", "a_specific_set")
obj2 = Palsy::Set.new("some_sets", "a_specific_set")
obj3 = Palsy::Set.new("some_sets", "a_different_set")

obj1 == obj2 #=> true
obj1.add 2
obj2.include? 2 #=> also true
obj3 == obj1 #=> false (different set keys)
obj.add 2
obj3.add 3
obj2.include? 3 #=> also false

Direct Known Subclasses

Map

Instance Attribute Summary

Attributes inherited from Generic

#db, #object_name, #table_name

Instance Method Summary collapse

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

#add(key) ⇒ Object

Add a value to the set – if it exists already, it will be replaced to avoid raising a constraint from sqlite.



43
44
45
46
# File 'lib/palsy/basic/set.rb', line 43

def add(key)
  delete(key)
  @db.execute("insert into #{@table_name} (name, key) values (?, ?)", [@object_name, Marshal.dump(key)])
end

#clearObject

Remove all values from the set.



67
68
69
# File 'lib/palsy/basic/set.rb', line 67

def clear
  @db.execute("delete from #{@table_name} where name=?", [@object_name])
end

#create_tableObject

Defines the schema for a set.



102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/palsy/basic/set.rb', line 102

def create_table
  @db.execute <<-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,
      UNIQUE(name, key) 
    )
  EOF

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

#delete(key) ⇒ Object

Remove a value from the Set.



51
52
53
# File 'lib/palsy/basic/set.rb', line 51

def delete(key)
  @db.execute("delete from #{@table_name} where name=? and key=?", [@object_name, Marshal.dump(key)])
end

#eachObject

Iterate over the set and yield each item. Modifications made to the values yielded will not be persisted.



95
96
97
# File 'lib/palsy/basic/set.rb', line 95

def each
  keys.each { |x| yield x }
end

#has_key?(key) ⇒ Boolean Also known as: include?

Predicate to determine if a value is in this set.

Returns:

  • (Boolean)


58
59
60
# File 'lib/palsy/basic/set.rb', line 58

def has_key?(key)
  @db.execute("select count(*) from #{@table_name} where name=? and key=?", [@object_name, Marshal.dump(key)]).first.first.to_i > 0
end

#keysObject

Return a ruby Array of the set. Used for #to_a and #to_set by various Ruby libraries.



88
89
90
# File 'lib/palsy/basic/set.rb', line 88

def keys
  @db.execute("select distinct key from #{@table_name} where name=?", [@object_name]).map { |x| Marshal.load(x.first) }
end

#replace(set) ⇒ Object

Replace the existing contents of the set with the contents of another set, or any Enumerable that has a set of unique values.



75
76
77
78
79
80
81
82
83
# File 'lib/palsy/basic/set.rb', line 75

def replace(set)
  clear

  return if set.empty?

  value_string = ("(?, ?)," * set.count).chop

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