AnyEvent-DBI

 view release on metacpan or  search on metacpan

t/fake-mysql  view on Meta::CPAN

checked in the order specified.

C<--dsn> - specifies a L<DBI> DSN. All queries that did not match a rule or
where the rule rewrote the query or did not return any response or a result set
on its own will be forwarded to that database. Individual rules can forward
specific queries to specific DSNs. If you do not want non-matching queries to
be forwarded, either create a match-all rule at the bottom of your last
configuration file or omit the C<--dsn> option. If you omit the option, an
error message will be sent to the client.

C<--dsn_user> and C<--dsn_password> can be used to specify username and
password for DBI drivers where those can not be specified in the DSN string.

=head1 RULES

Rules to be executed are contained in configuration files. The configuration
files are actually standard perl scripts and are executed as perl
subroutines. Therefore, they can contain any perl code -- the only requirement
is that the last statement in the file (that is, the return value of the file)
is an array containing the rules to be executed.

The actions from a rule will be executed for all queries that match a specific

t/fake-mysql  view on Meta::CPAN

If both C<command> and C<match> are specified, both must match for the rule to
be executed.

C<dbh> if specified, any matching query will be forwarded to this database
handle (possibly after a C<rewrite>), rather than the default handle specifeid
on the command line.

C<dsn> behaves identically, however a database handle is contructed from the
C<dsn> provided and an attempt is made to connect to the database. If C<dsn> is
a reference to an array, the first item from the array is used as a DSN, the
second one is used as username and the third one is used as password.

C<before> this can be a reference to a subroutine that will be called after a
matching query has been encountered but before any further processing has taken
place. The subroutine will be called with the text of the query as the first
argument, followed by extra arguments containing the strings matched from any
parenthesis found in the C<match> regular expression.  You can use C<before> to
execute any extra queries before the main query, such as C<EXPLAIN>. The return
value from the C<before> subroutine is discarded and is not used.

C<rewrite> is a string that will replace the original query that matches the

t/fake-mysql  view on Meta::CPAN


C<remote_host> contains the IP of the client.

C<dbh> and C<dsn> will contain a reference to the default DBI handle and the
DSN string it was produced from, as taken from the command line. Even if a
specific rule has its own C<dsn>, the value of those variables will always
refer to the default C<dbh> and C<dsn>. If you change the <dsn> variable, the
system will attempt to connect to the new dsn string and will produce a new
C<dbh> handle from it. If you set C<dsn> to an array reference, the first item
will be used as a DSN, the second one as a username and the third one as a
password. C<dsn_user> and C<dsn_password> can be used for the same purpose.

C<args> contains a reference to the C<@ARGV> array, that is, the command line
options that evoked myserver.pl

C<remote_dsn>, C<remote_dsn_user> and C<remote_dsn_password> are convenience
variables that can also be specified on the command line. It is not used by
C<myserver.pl> however you can use it in your rules, the way
C<remotequery.conf> does.

=head1 SECURITY

By default the script will only accept incoming connections from the local
host. If you relax that via the C<--interface> command-line option, all
connections will be accepted. However, once the connection has been
established, you can implement access control as demonstrated in the first rule

t/fake-mysql  view on Meta::CPAN


=head2 Remote queries - remotequery.conf

This rule set implements a C<SELECT REMOTE select_query ON 'dsn'> operator
which will execute the query on <dsn> specified, bring the results back into a
temporary table on the default server and substitute the C<REMOTE_SELECT> part
in the orignal query with a reference to the temoporary table. The following
scenarios are possible:

	# Standalone usage
	mysql> SELECT REMOTE * FROM mysql.user ON 'dbi:mysql:host=remote:user=foo:password=bar'

	# CREATE ... SELECT usage
	mysql> CREATE TABLE local_table SELECT REMOTE * FROM remote_table ON 'dbi:mysql:host=remote'

	# Non-correlated subquery
	mysql> SELECT *
	mysql> FROM (SELECT REMOTE * FROM mysql_user ON 'dbi:mysql:host=remote:user=foo:password=bar')
	mysql> WHERE user = 'mojo'

	# Specify remote dsn on the command line
	shell> ./myserver.pl --config=remotequery.conf --dsn=dbi:mysql: --remote_dsn=dbi:mysql:host=host2
	mysql> select remote 1;

	# Specify remote dsn as variable

	mysql> set @@@remote_dsn=dbi:mysql:host=host2
	mysql> select remote NOW();

t/fake-mysql  view on Meta::CPAN

use Socket;
use DBI;
use DBIx::MyServer;
use DBIx::MyServer::DBI;
use Getopt::Long qw(:config pass_through);

$SIG{CHLD} = 'IGNORE';

my $start_dsn;
my $start_dsn_user;
my $start_dsn_password;

my $remote_dsn;
my $remote_dsn_user;
my $remote_dsn_password;

my $port = '23306';
my $interface = '127.0.0.1';
my $debug;
my @config_names;
my @rules;
my %storage;

my @args = @ARGV;

my $result = GetOptions(
	"dsn=s"			=> \$start_dsn,
	"dsn_user=s"		=> \$start_dsn_user,
	"dsn_password=s"	=> \$start_dsn_password,
	"remote_dsn=s"		=> \$remote_dsn,
	"remote_dsn_user=s"	=> \$remote_dsn_user,
	"remote_dsn_password=s"	=> \$remote_dsn_password,
	"port=i"		=> \$port,
	"config=s"		=> \@config_names,
	"if|interface|ip=s"	=> \$interface,
	"debug"			=> \$debug
) or die;

@ARGV = @args;

my $start_dbh;
if (defined $start_dsn) {
	print localtime()." [$$] Connecting to DSN $start_dsn.\n" if $debug;
	$start_dbh = DBI->connect($start_dsn, $start_dsn_user, $start_dsn_password);
}

$storage{dbh} = $start_dbh;
$storage{dsn} = $start_dsn;
$storage{dsn_user} = $start_dsn_user;
$storage{dsn_password} = $start_dsn_password;

$storage{remote_dsn} = $remote_dsn;
$storage{remote_dsn_user} = $remote_dsn_user;
$storage{remote_dsn_password} = $remote_dsn_password;

foreach my $config_name (@config_names) {
	my $config_sub;
	open (CONFIG_FILE, $config_name) or die "unable to open $config_name: $!";
	read (CONFIG_FILE, my $config_text, -s $config_name);
	close (CONFIG_FILE);
	eval ('$config_sub = sub { '.$config_text.'}') or die $@;
	my @config_rules = &$config_sub();
	push @rules, @config_rules;
	print localtime()." [$$] Loaded ".($#config_rules + 1)." rules from $config_name.\n" if $debug;

t/fake-mysql  view on Meta::CPAN

				( ($i == $#rules) || (defined $rule->{dbh}) || (defined $rule->{forward}) )
			) {
				if (defined $rule->{dbh}) {
					$myserver->setDbh($rule->{dbh});
				} elsif (defined $rule->{dsn}) {
					if (ref($rule->{dsn}) eq 'ARRAY') {
						print localtime()." [$$] Connecting to DSN $rule->{dsn}->[0].\n" if $debug;
						$myserver->setDbh(DBI->connect(@{$rule->{dsn}}));
					} else {
						print localtime()." [$$] Connecting to DSN $rule->{dsn}.\n" if $debug;
						$myserver->setDbh(DBI->connect($rule->{dsn}, get('dsn_user'), get('dsn_password')));
					}
				}
				if (not defined get('dbh')) {
					error("No --dbh specified. Can not forward query.",1235, 42000);
				} elsif ($command == DBIx::MyServer::COM_QUERY) {
					(my $foo, $definitions, $data) = $myserver->comQuery($outgoing_query);
				} elsif ($command == DBIx::MyServer::COM_INIT_DB) {
					(my $foo, $definitions, $data) = $myserver->comInitDb($outgoing_query);
				} else {
					error("Don't know how to handle command $command.",1235, 42000);

t/fake-mysql  view on Meta::CPAN

	my ($name, $value) = @_;
	$storage{$name} = $value;
	if ($name eq 'dsn') {
		if (defined $value) {
			my $dbh;
			if (ref($value) eq 'ARRAY') {
				print localtime()." [$$] Connecting to DSN $value->[0].\n" if $debug;
				$dbh = DBI->connect(@{$value});
			} else {
				print localtime()." [$$] Connecting to DSN $value.\n" if $debug;
				$dbh = DBI->connect($value, get('dsn_user'), get('dsn_password'));
			}
			$storage{myserver}->setDbh($dbh);
			$storage{dbh} = $dbh;
		} else {
			$storage{myserver}->setDbh(undef);
			$storage{dbh} = undef;
		}
	}
	return 1;
}



( run in 0.880 second using v1.01-cache-2.11-cpan-49f99fa48dc )