1 package OpenSRF::Application::Persist;
2 use base qw/OpenSRF::Application/;
3 use OpenSRF::Application;
5 use OpenSRF::Utils::SettingsClient;
6 use OpenSRF::EX qw/:try/;
7 use OpenSRF::Utils::Logger;
11 use vars qw/$dbh $sc $log/;
14 $log = 'OpenSRF::Utils::Logger';
16 $sc = OpenSRF::Utils::SettingsClient->new;
18 my $dbfile = $sc->config_value( apps => persist => app_settings => 'dbfile');
20 throw OpenSRF::EX::PANIC ("Can't find my dbfile for SQLite!");
23 my $init_dbh = DBI->connect("dbi:SQLite:dbname=$dbfile","","");
24 $init_dbh->{AutoCommit} = 1;
25 $init_dbh->{RaiseError} = 0;
27 $init_dbh->do( <<" SQL" );
28 CREATE TABLE storage (
29 id INTEGER PRIMARY KEY,
35 $init_dbh->do( <<" SQL" );
36 CREATE TABLE store_name (
37 id INTEGER PRIMARY KEY,
45 $sc = OpenSRF::Utils::SettingsClient->new;
47 my $dbfile = $sc->config_value( apps => persist => app_settings => 'dbfile');
49 throw OpenSRF::EX::PANIC ("Can't find my dbfile for SQLite!");
52 $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile","","");
53 $dbh->{AutoCommit} = 1;
54 $dbh->{RaiseError} = 0;
62 my $name = shift || '';
73 throw OpenSRF::EX::WARN ("Duplicate key: object name [$name] already exists! " . $dbh->errstr)
76 my $sth = $dbh->prepare("INSERT INTO store_name (name) VALUES (?);");
81 my $last_id = $dbh->last_insert_id(undef, undef, 'store_name', 'id');
82 $name = 'AUTOGENERATED!!'.$last_id;
83 $dbh->do("UPDATE store_name SET name = '$name' WHERE id = '$last_id';");
88 __PACKAGE__->register_method(
89 api_name => 'opensrf.persist.slot.create',
90 method => 'create_store',
100 my $name = shift or do {
101 throw OpenSRF::EX::WARN ("No name specified!");
103 my $value = shift || '';
105 my $name_id = _get_name_id($name);
107 if ($self->api_name =~ /object/) {
108 $dbh->do('DELETE FROM storage WHERE name_id = ?;', {}, $name_id);
111 $dbh->do('INSERT INTO storage (name_id,value) VALUES (?,?);', {}, $name_id, JSON->perl2JSON($value));
113 return 0 if ($dbh->err);
116 __PACKAGE__->register_method(
117 api_name => 'opensrf.persist.object.set',
118 method => 'add_item',
121 __PACKAGE__->register_method(
122 api_name => 'opensrf.persist.queue.push',
123 method => 'add_item',
126 __PACKAGE__->register_method(
127 api_name => 'opensrf.persist.stack.push',
128 method => 'add_item',
133 my $name = shift or do {
134 throw OpenSRF::EX::WARN ("No queue name specified!");
138 my $name_id = $dbh->selectrow_arrayref("SELECT id FROM store_name WHERE name = ?;", {}, $name);
140 if (!ref($name_id) || !defined($name_id->[0])) {
141 throw OpenSRF::EX::WARN ("Object name [$name] does not exist!");
144 return $name_id->[0];
153 my $name_id = _get_name_id($name);
155 $dbh->do("DELETE FROM storage WHERE name_id = ?;", {}, $name_id);
156 $dbh->do("DELETE FROM store_name WHERE id = ?;", {}, $name_id);
159 __PACKAGE__->register_method(
160 api_name => 'opensrf.persist.slot.destroy',
161 method => 'destroy_store',
167 if ($name =~ /^AUTOGENERATED!!/) {
168 my $name_id = _get_name_id($name);
169 my $count = $dbh->selectrow_arrayref("SELECT COUNT(*) FROM storage WHERE name_id = ?;", {}, $name_id);
170 if (!ref($count) || $$count[0] == 0) {
171 $dbh->do("DELETE FROM store_name WHERE name = ?;", {}, $name);
180 my $name = shift or do {
181 throw OpenSRF::EX::WARN ("No queue name specified!");
183 my $name_id = _get_name_id($name);
185 my $value = $dbh->selectrow_arrayref('SELECT id, value FROM storage WHERE name_id = ? ORDER BY id ASC LIMIT 1;', {}, $name_id);
186 $dbh->do('DELETE FROM storage WHERE id = ?;',{}, $value->[0]) unless ($self->api_name =~ /peek$/);
188 _flush_by_name($name);
190 return JSON->JSON2perl( $value->[1] );
192 __PACKAGE__->register_method(
193 api_name => 'opensrf.persist.queue.peek',
194 method => 'pop_queue',
197 __PACKAGE__->register_method(
198 api_name => 'opensrf.persist.queue.pop',
199 method => 'pop_queue',
208 my $name = shift or do {
209 throw OpenSRF::EX::WARN ("No slot name specified!");
211 my $name_id = _get_name_id($name);
214 $order = 'DESC' if ($self->api_name =~ /stack/o);
216 my $values = $dbh->selectall_arrayref("SELECT value FROM storage WHERE name_id = ? ORDER BY id $order;", {}, $name_id);
218 $client->respond( JSON->JSON2perl( $_->[0] ) ) for (@$values);
222 __PACKAGE__->register_method(
223 api_name => 'opensrf.persist.queue.peek.all',
224 method => 'peek_slot',
228 __PACKAGE__->register_method(
229 api_name => 'opensrf.persist.stack.peek.all',
230 method => 'peek_slot',
240 my $name = shift or do {
241 throw OpenSRF::EX::WARN ("No queue name specified!");
243 my $name_id = _get_name_id($name);
245 my $value = $dbh->selectrow_arrayref('SELECT SUM(LENGTH(value)) FROM storage WHERE name_id = ?;', {}, $name_id);
247 return JSON->JSON2perl( $value->[0] );
249 __PACKAGE__->register_method(
250 api_name => 'opensrf.persist.queue.size',
251 method => 'shift_stack',
254 __PACKAGE__->register_method(
255 api_name => 'opensrf.persist.stack.size',
256 method => 'shift_stack',
259 __PACKAGE__->register_method(
260 api_name => 'opensrf.persist.object.size',
261 method => 'shift_stack',
269 my $name = shift or do {
270 throw OpenSRF::EX::WARN ("No queue name specified!");
272 my $name_id = _get_name_id($name);
274 my $value = $dbh->selectrow_arrayref('SELECT COUNT(*) FROM storage WHERE name_id = ?;', {}, $name_id);
276 return JSON->JSON2perl( $value->[0] );
278 __PACKAGE__->register_method(
279 api_name => 'opensrf.persist.queue.length',
280 method => 'shift_stack',
283 __PACKAGE__->register_method(
284 api_name => 'opensrf.persist.stack.depth',
285 method => 'shift_stack',
293 my $name = shift or do {
294 throw OpenSRF::EX::WARN ("No queue name specified!");
296 my $name_id = _get_name_id($name);
298 my $value = $dbh->selectrow_arrayref('SELECT id, value FROM storage WHERE name_id = ? ORDER BY id DESC LIMIT 1;', {}, $name_id);
299 $dbh->do('DELETE FROM storage WHERE id = ?;',{}, $value->[0]) unless ($self->api_name =~ /peek$/);
301 _flush_by_name($name);
303 return JSON->JSON2perl( $value->[1] );
305 __PACKAGE__->register_method(
306 api_name => 'opensrf.persist.stack.peek',
307 method => 'shift_stack',
310 __PACKAGE__->register_method(
311 api_name => 'opensrf.persist.stack.pop',
312 method => 'shift_stack',
320 my $name = shift or do {
321 throw OpenSRF::EX::WARN ("No object name specified!");
324 my $name_id = _get_name_id($name);
326 my $value = $dbh->selectrow_arrayref('SELECT name_id, value FROM storage WHERE name_id = ? ORDER BY id DESC LIMIT 1;', {}, $name_id);
327 $dbh->do('DELETE FROM storage WHERE name_id = ?',{}, $value->[0]) unless ($self->api_name =~ /peek$/);
329 _flush_by_name($name);
331 return JSON->JSON2perl( $value->[1] );
333 __PACKAGE__->register_method(
334 api_name => 'opensrf.persist.object.peek',
335 method => 'shift_stack',
338 __PACKAGE__->register_method(
339 api_name => 'opensrf.persist.object.get',
340 method => 'shift_stack',