3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-12-26 20:52:37 +01: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 {
my ($self, %opts) = @_;
my ($self, @opts) = @_;
my $sth = eval {
my $sql = 'SELECT ';
my @keys = ();
my @values = ();
my @where = ();
my @sort = ();
my $everything = 0;
foreach my $key (keys %opts) {
next if $key eq '_sort';
foreach my $expr (@opts) {
my ($key, $op, $value) = split /\s*([!=<>]+)\s*/, $expr, 3;
if ($key eq '_everything') {
$everything = 1;
push @keys, '*';
next;
}
if (defined $opts{$key}) {
if ($key =~ s/^!//) {
push @where, qq{"$key" != ?};
if ($key eq '_sort') {
if ($value =~ /^\-/) {
push @sort, "$value DESC";
} 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 .= ' FROM Stuff WHERE ';
$sql .= join ' AND ', @where;
$sql .= qq{ORDER BY "$opts{_sort}"} if defined $opts{_sort};
$sql .= join ' ', @where;
$sql .= ' ORDER BY ' . join(', ', @sort) if @sort;
my $sth = $self->{dbh}->prepare($sql);
my $param = 0;
foreach my $key (keys %opts) {
next if $key eq '_everything' or $key eq '_sort';
$sth->bind_param(++$param, $opts{$key}) if defined $opts{$key};
foreach my $value (@values) {
$sth->bind_param(++$param, $value);
}
$sth->execute;
@ -408,9 +430,9 @@ sub get_next {
}
sub get_all {
my ($self, %opts) = @_;
my ($self, @opts) = @_;
my $sth = $self->get_each(%opts);
my $sth = $self->get_each(@opts);
my $data = eval {
return $sth->fetchall_arrayref({});

View File

@ -1321,7 +1321,7 @@ sub factfind {
foreach my $chan (sort $factoids->get_keys) {
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;
if ($owner eq '.*') {

View File

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