aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2015-04-01 22:01:50 +0300
committerSergey Poznyakoff <gray@gnu.org>2015-04-01 22:09:13 +0300
commit277338c6e5d4a1f404b718202a48894df116542f (patch)
treee60b66d5c86b61b1a87124f705e9c9c480126d9f
parentaa0a3f7cbd7fd1b230386f434ad472bc06f01b6e (diff)
downloaddnstools-277338c6e5d4a1f404b718202a48894df116542f.tar.gz
dnstools-277338c6e5d4a1f404b718202a48894df116542f.tar.bz2
nsdbimport: use prepare/execute approach
* nsdbimport/nsdbimport (parse_opts): New function. (readconfig): Special parsing for *-query statements. The values is a reference to array of 2 elements: the template (with placeholders) and an array for creating parameters (governor). (replvar): Third argument is a reference to governor. (query_expand): Remove. (sql_query): Use prepare_cached/execute. In debug mode, perform parameter substitution in a printable copy of the template.
-rwxr-xr-xnsdbimport/nsdbimport86
1 files changed, 55 insertions, 31 deletions
diff --git a/nsdbimport/nsdbimport b/nsdbimport/nsdbimport
index 7c72f71..8b8fcca 100755
--- a/nsdbimport/nsdbimport
+++ b/nsdbimport/nsdbimport
@@ -71,6 +71,22 @@ END {
my %config;
+sub parse_opts {
+ my $opt = shift;
+
+ if (defined($opt)) {
+ my %option;
+ foreach my $x (split /,/, $opt) {
+ if ($x =~ /([?+\.@-])(.*)/) {
+ $option{$1} = $2;
+ }
+ }
+ return \%option;
+ }
+
+ return undef;
+}
+
sub readconfig {
my ($file, $kw) = @_;
open(my $fd, "<", $file)
@@ -102,10 +118,21 @@ sub readconfig {
++$err;
next;
}
- $config{$k} = $v;
+
+ if ($k =~ /.*-query$/) {
+ my @params;
+
+ $v =~ s/\$\{([\w_-]+)(?::(.+?))?\}/push @params, { var => $1, opt => parse_opts($2) }; '?'/gex;
+ $v =~ s/'\?'/?/g;
+ $v =~ s/"\?"/?/g;
+ $config{$k} = [ $v, \@params ];
+ } else {
+ $config{$k} = $v;
+ }
}
close $fd;
exit(EX_CONFIG) if $err;
+
abend(EX_CONFIG, "rr-query is not defined in $file")
unless defined($config{'rr-query'});
}
@@ -155,53 +182,52 @@ my $rx_rr = array_to_regexp(@rrtypes);
# ###################
sub replvar {
my ($rec, $var, $opt) = @_;
- my %option;
- if (defined($opt)) {
- foreach my $x (split /,/, $opt) {
- if ($x =~ /([?+\.@-])(.*)/) {
- $option{$1} = $2;
- }
- }
- }
my $val = $rec->{$var} || '';
if ($val eq '') {
- if (defined($option{'-'})) {
- $val = $option{'-'};
- } elsif (defined($option{'?'})) {
- my $text = $option{'?'} || "$var not defined";
+ if (defined($opt->{'-'})) {
+ $val = $opt->{'-'};
+ } elsif (defined($opt->{'?'})) {
+ my $text = $opt->{'?'} || "$var not defined";
error($text, prefix => $rec->{locus});
}
- } elsif (defined($option{'+'})) {
- $val = $option{'+'};
+ } elsif (defined($opt->{'+'})) {
+ $val = $opt->{'+'};
}
if ($val ne '') {
- if ($val eq '@' and defined($option{'@'})) {
- $val = $option{'@'} || $rec->{origin};
+ if ($val eq '@' and defined($opt->{'@'})) {
+ $val = $opt->{'@'} || $rec->{origin};
$val .= '.' unless $val =~ /\.$/;
- } elsif (defined($option{'.'}) and $val !~ /\.$/) {
- $val .= '.' . ($option{'.'} || $rec->{origin});
+ } elsif (defined($opt->{'.'}) and $val !~ /\.$/) {
+ $val .= '.' . ($opt->{'.'} || $rec->{origin});
$val .= '.' unless $val =~ /\.$/;
}
}
return $val;
}
-sub query_expand {
- my ($q, $rec) = @_;
- $q =~ s/\$\{([\w_-]+)(?::(.+?))?\}/replvar($rec, $1, $2)/gex;
- debug(2, "$rec->{locus}: $q");
- return $q;
-}
-
sub sql_query {
my ($tmpl, $rec) = @_;
- my $q = query_expand($tmpl, $rec);
+
+ my $sth = $dbd->prepare_cached($tmpl->[0]);
+ my @params;
+ foreach my $p (@{$tmpl->[1]}) {
+ push @params, replvar($rec, $p->{var}, $p->{opt});
+ }
+
+ if ($debug >= 2) {
+ my $printable = $tmpl->[0];
+ foreach my $p (@params) {
+ $printable =~ s/\?/\'$p\'/;
+ }
+ error("$printable", prefix => 'DEBUG');
+ }
+
unless ($dry_run) {
- $dbd->do($q)
- or abend(EX_UNAVAILABLE, $dbd->errstr."\nFailed query: $q");
+ $sth->execute(@params)
+ or abend(EX_UNAVAILABLE, $dbd->errstr);
}
++$record_count;
}
@@ -895,8 +921,6 @@ Exited due to errors in configuration file.
Only MySQL is supported and tested.
-Need to ensure proper quoting of SQL query arguments.
-
=head1 SEE ALSO
B<cfpeek>(1), B<named>(8), B<named.conf>(5).

Return to:

Send suggestions and report system problems to the System administrator.