[registry] improved tests, sqlite/tc bugfixes
[rbot] / lib / rbot / registry / sqlite.rb
1 #-- vim:sw=2:et
2 #++
3 #
4 # :title: Sqlite3 registry implementation
5 #
6
7 require 'sqlite3'
8
9 module Irc
10 class Bot
11 class Registry
12
13   class SqliteAccessor < AbstractAccessor
14
15     def initialize(filename)
16       super filename + '.db'
17     end
18
19     def registry
20       super
21       unless @registry
22         @registry = SQLite3::Database.new(@filename)
23         begin
24           @registry.execute('SELECT COUNT(*) FROM data')
25         rescue
26           @registry.execute('CREATE TABLE data (key PRIMARY KEY, value)')
27         end
28       end
29       @registry
30     end
31
32     def optimize
33       return unless @registry
34       @registry.execute('VACUUM')
35     end
36
37     def [](key)
38       if dbexists?
39         begin
40           value = registry.get_first_row('SELECT value FROM data WHERE key = ?', key.to_s)
41           return restore(value.first)
42         rescue
43           return default
44         end
45       else
46         return default
47       end
48     end
49
50     def []=(key,value)
51       value = SQLite3::Blob.new(store(value))
52       if has_key? key
53         registry.execute('UPDATE data SET value = ? WHERE key = ?', value, key.to_s)
54       else
55         registry.execute('INSERT INTO data VALUES (?, ?)', key.to_s, value)
56       end
57     end
58
59     def each(&block)
60       return nil unless dbexists?
61       res = registry.execute('SELECT * FROM data')
62       res.each do |row|
63         key, value = row
64         block.call(key, restore(value))
65       end
66     end
67
68     alias each_pair each
69
70     def has_key?(key)
71       return nil unless dbexists?
72       res = registry.get_first_row('SELECT COUNT(*) FROM data WHERE key = ?', key.to_s)
73       return res.first > 0
74     end
75
76     alias include? has_key?
77     alias member? has_key?
78     alias key? has_key?
79
80     def has_value?(value)
81       return nil unless dbexists?
82       value = SQLite3::Blob.new(store(value))
83       res = registry.get_first_row('SELECT COUNT(*) FROM data WHERE value = ?', value)
84       return res.first > 0
85     end
86
87     def delete(key)
88       return default unless dbexists?
89       begin
90         value = self[key]
91         registry.execute('DELETE FROM data WHERE key = ?', key.to_s)
92         value if registry.changes > 0
93       rescue
94         nil
95       end
96     end
97
98     # returns a list of your keys
99     def keys
100       return [] unless dbexists?
101       res = registry.execute('SELECT key FROM data')
102       res.map { |row| row.first }
103     end
104
105     def clear
106       return unless dbexists?
107       registry.execute('DELETE FROM data')
108     end
109
110     alias truncate clear
111
112     # returns the number of keys in your registry namespace
113     def length
114       return 0 unless dbexists?
115       res = registry.get_first_row('SELECT COUNT(key) FROM data')
116       res.first
117     end
118
119     alias size length
120
121   end
122
123 end # Registry
124 end # Bot
125 end # Irc
126