3
0
mirror of https://github.com/pragma-/pbot.git synced 2025-10-14 23:17:22 +02:00

DualIndexSQLiteObject: refactor get_each() to use array instead of hash

This commit is contained in:
Pragmatic Software 2020-03-03 07:40:23 -08:00
parent 786dfc8c6c
commit 3ff232decd
3 changed files with 49 additions and 24 deletions

View File

@ -341,43 +341,65 @@ sub get_keys {
} }
sub get_each { sub get_each {
my ($self, %opts) = @_; my ($self, @opts) = @_;
my $sth = eval { my $sth = eval {
my $sql = 'SELECT '; my $sql = 'SELECT ';
my @keys = (); my @keys = ();
my @values = ();
my @where = (); my @where = ();
my @sort = ();
my $everything = 0;
foreach my $key (keys %opts) { foreach my $expr (@opts) {
next if $key eq '_sort'; my ($key, $op, $value) = split /\s*([!=<>]+)\s*/, $expr, 3;
if ($key eq '_everything') { if ($key eq '_everything') {
$everything = 1;
push @keys, '*'; push @keys, '*';
next; next;
} }
if (defined $opts{$key}) { if ($key eq '_sort') {
if ($key =~ s/^!//) { if ($value =~ /^\-/) {
push @where, qq{"$key" != ?}; push @sort, "$value DESC";
} else { } else {
push @where, qq{"$key" = ?}; push @sort, "$value ASC";
} }
next;
} }
push @keys, $key unless $opts{_everything}; if (defined $op) {
my $prefix = 'AND ';
if ($op eq '=' or $op eq '==') {
$op = '=';
} elsif ($op eq '!=' or $op eq '<>') {
$op = '!=';
}
if ($key =~ s/^(OR\s+|AND\s+)//) {
$prefix = $1;
}
$prefix = '' if not @where;
push @where, qq{$prefix"$key" $op ?};
push @values, $value;
}
push @keys, $key unless $everything or grep { $_ eq $key } @keys;
} }
$sql .= join ', ', @keys; $sql .= join ', ', @keys;
$sql .= ' FROM Stuff WHERE '; $sql .= ' FROM Stuff WHERE ';
$sql .= join ' AND ', @where; $sql .= join ' ', @where;
$sql .= qq{ORDER BY "$opts{_sort}"} if defined $opts{_sort}; $sql .= ' ORDER BY ' . join(', ', @sort) if @sort;
my $sth = $self->{dbh}->prepare($sql); my $sth = $self->{dbh}->prepare($sql);
my $param = 0; my $param = 0;
foreach my $key (keys %opts) { foreach my $value (@values) {
next if $key eq '_everything' or $key eq '_sort'; $sth->bind_param(++$param, $value);
$sth->bind_param(++$param, $opts{$key}) if defined $opts{$key};
} }
$sth->execute; $sth->execute;
@ -408,9 +430,9 @@ sub get_next {
} }
sub get_all { sub get_all {
my ($self, %opts) = @_; my ($self, @opts) = @_;
my $sth = $self->get_each(%opts); my $sth = $self->get_each(@opts);
my $data = eval { my $data = eval {
return $sth->fetchall_arrayref({}); return $sth->fetchall_arrayref({});

View File

@ -1321,7 +1321,7 @@ sub factfind {
foreach my $chan (sort $factoids->get_keys) { foreach my $chan (sort $factoids->get_keys) {
next if defined $channel and $chan !~ /^$channel$/i; next if defined $channel and $chan !~ /^$channel$/i;
foreach my $factoid ($factoids->get_all(index1 => $chan, index2 => undef, owner => undef, ref_user => undef, edited_by => undef, action => undef)) { foreach my $factoid ($factoids->get_all("index1 = $chan", 'index2', 'owner', 'ref_user', 'edited_by', 'action')) {
my $match = 0; my $match = 0;
if ($owner eq '.*') { if ($owner eq '.*') {

View File

@ -192,8 +192,8 @@ sub export_factoids {
print FILE "</tr>\n</thead>\n<tbody>\n"; print FILE "</tr>\n</thead>\n<tbody>\n";
$table_id++; $table_id++;
my $iter = $self->{factoids}->get_each(index1 => $channel, _everything => 1, _sort => 'index1'); my $iter = $self->{factoids}->get_each("index1 = $channel", '_everything', '_sort = index1');
while ((my $factoid = $self->{factoids}->get_next($iter)) != undef) { while (defined (my $factoid = $self->{factoids}->get_next($iter))) {
my $trigger_name = $self->{factoids}->get_data($factoid->{index1}, $factoid->{index2}, '_name'); my $trigger_name = $self->{factoids}->get_data($factoid->{index1}, $factoid->{index2}, '_name');
if ($factoid->{type} eq 'text') { if ($factoid->{type} eq 'text') {
$i++; $i++;
@ -320,6 +320,7 @@ sub find_factoid {
if ($opts{exact_channel} and not $opts{exact_trigger}) { if ($opts{exact_channel} and not $opts{exact_trigger}) {
if (not $self->{factoids}->exists($from, $keyword)) { if (not $self->{factoids}->exists($from, $keyword)) {
($channel, $trigger) = ($from, $keyword);
goto CHECK_REGEX if $from eq '.*'; goto CHECK_REGEX if $from eq '.*';
goto CHECK_REGEX if not $self->{factoids}->exists('.*', $keyword); goto CHECK_REGEX if not $self->{factoids}->exists('.*', $keyword);
($channel, $trigger) = ('.*', $keyword); ($channel, $trigger) = ('.*', $keyword);
@ -330,7 +331,7 @@ sub find_factoid {
} }
if (not $opts{exact_channel}) { if (not $opts{exact_channel}) {
foreach my $factoid ($self->{factoids}->get_all(index2 => $keyword, index1 => undef, action => undef)) { foreach my $factoid ($self->{factoids}->get_all("index2 = $keyword", 'index1', 'action')) {
$channel = $factoid->{index1}; $channel = $factoid->{index1};
$trigger = $keyword; $trigger = $keyword;
@ -371,10 +372,13 @@ sub find_factoid {
my @factoids; my @factoids;
if ($opts{exact_channel}) { if ($opts{exact_channel}) {
@factoids = $self->{factoids}->get_all(type => 'regex', index1 => $channel, index2 => undef, action => undef); if ($channel ne '.*') {
push @factoids, $self->{factoids}->get_all(type => 'regex', index1 => '.*', index2 => undef, action => undef); @factoids = $self->{factoids}->get_all('type = regex', "index1 = $channel", 'OR index1 = .*', 'index2', 'action');
} else {
@factoids = $self->{factoids}->get_all('type = regex', "index1 = $channel", 'index2', 'action');
}
} else { } else {
@factoids = $self->{factoids}->get_all(type => 'regex', index1 => undef, index2 => undef, action => undef); @factoids = $self->{factoids}->get_all('type = regex', 'index1', 'index2', 'action');
} }
foreach my $factoid (@factoids) { foreach my $factoid (@factoids) {
@ -383,7 +387,6 @@ sub find_factoid {
$action = $factoid->{action}; $action = $factoid->{action};
if ($string =~ /$trigger/) { if ($string =~ /$trigger/) {
if ($opts{find_alias}) { if ($opts{find_alias}) {
my $command = $action; my $command = $action;
my $arglist = $self->{pbot}->{interpreter}->make_args($command); my $arglist = $self->{pbot}->{interpreter}->make_args($command);
@ -783,7 +786,7 @@ sub interpreter {
my ($fwd_chan, $fwd_trig); my ($fwd_chan, $fwd_trig);
# build list of which channels contain the keyword, keeping track of the last one and count # build list of which channels contain the keyword, keeping track of the last one and count
foreach my $factoid ($self->{factoids}->get_all(index2 => $original_keyword, index1 => undef, type => undef)) { foreach my $factoid ($self->{factoids}->get_all("index2 = $original_keyword", 'index1', 'type')) {
next if $factoid->{type} ne 'text' and $factoid->{type} ne 'module'; next if $factoid->{type} ne 'text' and $factoid->{type} ne 'module';
push @chanlist, $self->{factoids}->get_data($factoid->{index1}, '_name'); push @chanlist, $self->{factoids}->get_data($factoid->{index1}, '_name');
$fwd_chan = $factoid->{index1}; $fwd_chan = $factoid->{index1};