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
47
48
# File 'lib/palsy/basic/set.rb', line 43

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

#clearObject

Remove all values from the set.



69
70
71
# File 'lib/palsy/basic/set.rb', line 69

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

#create_tableObject

Defines the schema for a set.



106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/palsy/basic/set.rb', line 106

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,
      UNIQUE(name, key) 
    )
  EOF

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

#delete(key) ⇒ Object

Remove a value from the Set.



53
54
55
# File 'lib/palsy/basic/set.rb', line 53

def delete(key)
  @db.execute_t("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.



99
100
101
# File 'lib/palsy/basic/set.rb', line 99

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)


60
61
62
# File 'lib/palsy/basic/set.rb', line 60

def has_key?(key)
  @db.execute_t("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.



92
93
94
# File 'lib/palsy/basic/set.rb', line 92

def keys
  @db.execute_t("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.



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/palsy/basic/set.rb', line 77

def replace(set)
  @db.with_t do
    clear

    return if set.empty?

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

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