2 # General purpose file bashed key/value hash table system
3 # based on SQLite3 and storing one hash table per database
5 # Copyright (c) 2010 Dirk Koopman G1TLH
17 unless ($done_require) {
23 dbg("SQLHash: no DBI available '$@'");
27 eval {require DBD::SQLite;};
29 dbg("SQLHash: no DBD::SQLite available '$@'");
41 my $fn = ref $pkg ? shift : $pkg;
55 if ($dsnfn =~ /\.sqlite$/) {
56 $table =~ s/\.sqlite$//;
61 my $blob = delete $flags{blob} ? 'blob' : 'text';
62 $flags{RaiseError} = 0 unless exists $flags{RaiseError};
63 my $exists = file_exists($dsnfn);
65 my $dsn = "dbi:SQLite:dbname=$fn";
66 my $dbh = DBI->connect($dsn, "", "", \%flags);
69 my $r = _sql_do($dbh, qq{create table $table (k text unique key not null, v $blob not null)});
70 dbg("SQLHash: created $table with data as $blob") if $r;
72 return bless {dbh => $dbh, table => $table}, $pkg;
78 return _sql_get_single($self->{dbh}, qq{select v from $self->{table} where k = ?}, @_);
84 _sql_do($self->{dbh}, qq{replace in $self->{table} (k,v) values(?,?)}, @_);
85 return @r ? $r[0]->[0] : undef;
91 _sql_do($self->{dbh}, qq{delete from $self->{table} where k = ?}, @_);
97 return _sql_get_simple_array($self->{dbh}, qq{select k from $self->{table}});
103 return _sql_get_simple_array($self->{dbh}, qq{select v from $self->{table}});
108 $_[0]->{dbh}->begin_work;
113 $_[0]->{dbh}->commit;
118 $_[0]->{dbh}->rollback;
125 dbg("SQL Error: '" . $dbh->errstr . "' on statement '$s', disconnecting");
132 dbg("sql => $s") if isdbg('sql');
133 my $sth = $dbh->prepare($s);
134 _error($dbh, $s), $return 0 unless $sth;
135 my $rv = $sth->execute(@_);
136 _error($dbh, $s) unless $rv;
145 my ($rv, $sth) = _sql_pre_exe($dbh, $s);
146 return $out unless $rv && $sth;
147 my $ref = $sth->fetch;
149 dbg("SQL Error: '" . $sth->errstr . "' on statement '$s'") if $sth->err;
151 dbg("sql <= " . join(',', @$ref)) if isdbg('sql');
158 sub _sql_get_simple_array
163 my ($rv, $sth) = _sql_pre_exe($dbh, $s);
164 return @out unless $rv && $sth;
165 while (my $ref = $sth->fetch) {
167 dbg("SQL Error: '" . $sth->errstr . "' on statement '$s'") if $sth->err;
170 dbg("sql <= " . join(',', @$ref)) if isdbg('sql');
171 push @out, $ref->[0];
183 my ($rv, $sth) = _sql_pre_exe($dbh, $s);
184 return @out unless $rv && $sth;
185 while (my $ref = $sth->fetch) {
187 dbg("SQL Error: '" . $sth->errstr . "' on statement '$s'") if $sth->err;
190 dbg("sql <= " . join(',', @$ref)) if isdbg('sql');
202 dbg("sql => $s") if isdbg('sql');
203 my $rv = $dbh->do($s, @_);
204 _error($dbh, $s) unless $rv;