view release on metacpan or search on metacpan
next unless $do =~ /^y/i;
print <<"EOF";
Please provide a username that can be used to connect to the $name
RDBMS? This user must have the ability to create a new
database/schema.
EOF
my $user = Module::Build->prompt( ' Username?' );
my $password;
if ($user)
{
$password = Module::Build->prompt( " Password for $user?" );
}
print <<"EOF";
What host is the $name RDBMS located on. Press enter to skip this if
the database server is located on the localhost or can be determined
in another way (for example, Oracle can use TNS to find the database).
EOF
my $host = Module::Build->prompt( ' Host?' );
Please provide a database name that can be used for testing. A
database/schema with this name will be created and dropped during the
testing process.
EOF
my $db_name = Module::Build->prompt( ' Database name?', "test_alzabo_$t" );
push @config,
{ rdbms => $t,
user => $user,
password => $password,
host => $host,
port => $port,
schema_name => $db_name,
};
}
return \@config;
}
lib/Alzabo/Create/Schema.pm view on Meta::CPAN
The name of the database with which to connect.
=item * rdbms => $rdbms
See the L<C<new>|new> method documentation for an explanation of this
parameter.
=back
In addition, this method takes any parameters that can be used when
connecting to the RDBMS, including "user", "password", "host", and
"port".
Returns a new C<Alzabo::Create::Schema> object.
=head2 Other Methods
=for pod_merge name
=head2 set_name ($name)
lib/Alzabo/Create/Schema.pm view on Meta::CPAN
database if necessary, and then execute whatever SQL is necessary to
make that database match the current state of the schema object. If
the schema has been instantiated previously, then it will generate the
SQL necessary to change the database. This may be destructive
(dropping tables, columns, etc) so be careful. This will cause the
schema to be marked as instantiated.
Wherever possible, existing data will be preserved.
This method takes any parameters that can be used when connecting to
the RDBMS, including "schema_name", "user", "password", "host", and
"port".
If a "schema_name" parameter is given, then this will be the name
given to the schema in the RDBMS.
B<Warning>: Every time you call C<create()> or C<sync_backend()>, the
schema will consider itself to have been instantiated. This will
affect how schema diffs are generated. After this, you will almost
certainly need to use C<sync_backend()> to sync the RDBMS schema,
since the schema's internal notion of it's state may be incorrect.
lib/Alzabo/Create/Schema.pm view on Meta::CPAN
schema object. See the L<C<create()>|Alzabo::Create::Schema/create>
method for more details.
=head2 drop
Drops the database/schema from the RDBMS. This will cause the schema
to be marked as not instantiated. This method does not delete the
Alzabo files from disk. To do this, call the C<delete()> method.
This method takes any parameters that can be used when connecting to
the RDBMS, including "schema_name", "user", "password", "host", and
"port".
Throws: L<C<Alzabo::Exception::Driver>|Alzabo::Exceptions>
=head2 sync_backend
This method will look at the schema as it exists in the RDBMS backend,
and make any changes that are necessary in order to make this backend
schema match the Alzabo schema object. If there is no corresponding
schema in the RDBMS backend, then this method is equivalent to the
lib/Alzabo/Create/Schema.pm view on Meta::CPAN
column "lengths" for all of its integer columns. Alzabo tries to
account for these.
In the end, this means that Alzabo may never think that a schema in
the RDBMS exactly matches the state of the Alzabo schema object. Even
immediately after running this method, running it again may still
cause it to execute SQL commands. Fortunately, the SQL it generates
will not cause anything to break.
This method takes any parameters that can be used when connecting to
the RDBMS, including "schema_name", "user", "password", "host", and
"port".
Throws: L<C<Alzabo::Exception::Driver>|Alzabo::Exceptions>
=head2 sync_backend_sql
If there is no corresponding schema in the RDBMS backend, then this
method returns the SQL necessary to create the schema from scratch.
This method takes any parameters that can be used when connecting to
the RDBMS, including "schema_name", "user", "password", "host", and
"port".
Throws: L<C<Alzabo::Exception::Driver>|Alzabo::Exceptions>
=head2 delete
Removes the schema object from disk. It does not delete the database
from the RDBMS. To do this you must call the L<C<drop>|drop> method
first.
lib/Alzabo/Driver.pm view on Meta::CPAN
The following methods are not implemented in C<Alzabo::Driver> itself
and must be implemented in a subclass.
=head3 Parameters for connect(), create_database(), and drop_database()
=over 4
=item * user => $db_username
=item * password => $db_pw
=item * host => $hostname
=item * port => $port
=back
All of these default to undef. See the appropriate DBD driver
documentation for more details.
lib/Alzabo/Driver/MySQL.pm view on Meta::CPAN
sub _connect_params
{
my $self = shift;
my %p = @_;
%p = validate( @_, { name => { type => SCALAR },
user => { type => SCALAR | UNDEF,
optional => 1 },
password => { type => SCALAR | UNDEF,
optional => 1 },
host => { type => SCALAR | UNDEF,
optional => 1 },
port => { type => SCALAR | UNDEF,
optional => 1 },
map { $_ => 0 } grep { /^mysql_/ } keys %p,
} );
my $dsn = "DBI:mysql:$p{name}";
$dsn .= ";host=$p{host}" if $p{host};
$dsn .= ";port=$p{port}" if $p{port};
foreach my $k ( grep { /^mysql_/ } keys %p )
{
$dsn .= ";$k=$p{$k}";
}
return [ $dsn, $p{user}, $p{password},
{ RaiseError => 1,
AutoCommit => 1,
PrintError => 0,
}
];
}
sub next_sequence_number
{
# This will cause an auto_increment column to go up (because we're
lib/Alzabo/Driver/PostgreSQL.pm view on Meta::CPAN
}
sub supports_referential_integrity { 1 }
sub schemas
{
my $self = shift;
my %p = validate( @_, { user => { type => SCALAR | UNDEF,
optional => 1 },
password => { type => SCALAR | UNDEF,
optional => 1 },
host => { type => SCALAR | UNDEF,
optional => 1 },
port => { type => SCALAR | UNDEF,
optional => 1 },
options => { type => SCALAR | UNDEF,
optional => 1 },
tty => { type => SCALAR | UNDEF,
optional => 1 },
} );
lib/Alzabo/Driver/PostgreSQL.pm view on Meta::CPAN
}
sub _connect_params
{
my $self = shift;
my %p = @_;
%p = validate( @_, { name => { type => SCALAR },
user => { type => SCALAR | UNDEF,
optional => 1 },
password => { type => SCALAR | UNDEF,
optional => 1 },
host => { type => SCALAR | UNDEF,
optional => 1 },
port => { type => SCALAR | UNDEF,
optional => 1 },
options => { type => SCALAR | UNDEF,
optional => 1 },
tty => { type => SCALAR | UNDEF,
optional => 1 },
service => { type => SCALAR | UNDEF,
lib/Alzabo/Driver/PostgreSQL.pm view on Meta::CPAN
} );
my $dsn = "dbi:Pg:dbname=$p{name}";
foreach ( qw( host port options tty service sslmode ) )
{
$dsn .= ";$_=$p{$_}" if grep { defined && length } $p{$_};
}
my %pg_keys = map { $_ => $p{$_} } grep { /^pg_/ } keys %p;
return [ $dsn, $p{user}, $p{password},
{ RaiseError => 1,
AutoCommit => 1,
PrintError => 0,
%pg_keys,
},
];
}
sub next_sequence_number
{
lib/Alzabo/Intro.pod view on Meta::CPAN
$table->insert( values => { create_date => NOW() } );
$row->update( pi => PI() );
my $cursor =
$table->rows_where( where =>
[ $table->column('expire_date'), '<=', NOW() ] );
my $cursor =
$table->rows_where( where =>
[ LENGTH( $table->column('password') ), '<=', 5 ] );
The documentation for the Alzabo::SQLMaker subclass for your RDBMS
will contain a detailed list of all exportable functions.
=head2 Row Objects Not in the Database
Sometimes you'll want to create an object with the row object API, but
which does not represent a row in the database. See the
L<C<Alzabo::Runtime::Row> documentation|Alzabo::Runtime::Row/POTENTIAL
ROWS> for details on how these objects can be created.
lib/Alzabo/Intro.pod view on Meta::CPAN
foreach my $c ( $t->columns )
{
if ( $c->is_primary_key and lc $c->type eq 'tinyint' )
{
$c->set_type('int');
$c->add_attribute('unsigned');
}
}
}
$schema->create( user => 'user', password => 'password' );
$schema->save_to_file;
Because Alzabo keeps track of the schema's state the last time it was
created in the RDBMS, the C<create()> method here will generate the
appropriate SQL to alter the RDBMS schema so that it matches the
schema as defined in Alzabo.
=head1 TRANSACTIONS
Alzabo uses transactions internally in order to guarantee consistency.
lib/Alzabo/QuickRef.pod view on Meta::CPAN
=for html_docs link=L<More|Alzabo::Create::Schema/load_from_file($name)>
=item * set_user ($user)
=for html_docs type=object
Set the username to be used when connecting to the database.
=for html_docs link=L<More|Alzabo::Runtime::Schema/set_user ($user)>
=item * set_password ($password)
=for html_docs type=object
Set the password to be used when connecting to the database.
=for html_docs link=L<More|Alzabo::Runtime::Schema/set_password ($password)>
=item * set_host ($host)
=for html_docs type=object
Set the host to be used when connecting to the database.
=for html_docs link=L<More|Alzabo::Runtime::Schema/set_host ($host)>
=item * connect (%params)
=for html_docs type=object
Connect to the RDBMS. This will use the previously set
username/password/host, though these can be overridden by the
C<%params> given to the call.
B<Important>: This method must be called before any data retrieval is
attempted.
=for html_docs link=L<More|Alzabo::Runtime::Schema/connect (%params)>
=item * join
=for html_docs type=object
lib/Alzabo/Runtime/Schema.pm view on Meta::CPAN
return 'runtime';
}
sub user
{
my $self = shift;
return $self->{user};
}
sub password
{
my $self = shift;
return $self->{password};
}
sub host
{
my $self = shift;
return $self->{host};
}
sub port
lib/Alzabo/Runtime/Schema.pm view on Meta::CPAN
$self->{db_schema_name} = shift;
}
sub set_user
{
my $self = shift;
$self->{user} = shift;
}
sub set_password
{
my $self = shift;
$self->{password} = shift;
}
sub set_host
{
my $self = shift;
$self->{host} = shift;
}
sub set_port
lib/Alzabo/Runtime/Schema.pm view on Meta::CPAN
$self->{quote_identifiers} = $val if defined $val;
}
sub connect
{
my $self = shift;
my %p;
$p{user} = $self->user if defined $self->user;
$p{password} = $self->password if defined $self->password;
$p{host} = $self->host if defined $self->host;
$p{port} = $self->port if defined $self->port;
$self->driver->connect( %p, @_ );
# $self->set_referential_integrity( ! $self->driver->supports_referential_integrity );
}
sub disconnect
{
my $self = shift;
lib/Alzabo/Runtime/Schema.pm view on Meta::CPAN
=head1 NAME
Alzabo::Runtime::Schema - Schema objects
=head1 SYNOPSIS
use Alzabo::Runtime::Schema qw(some_schema);
my $schema = Alzabo::Runtime::Schema->load_from_file( name => 'foo' );
$schema->set_user( $username );
$schema->set_password( $password );
$schema->connect;
=head1 DESCRIPTION
Objects in this class represent schemas, and can be used to retrieve
data from that schema.
This object can only be loaded from a file. The file is created
whenever a corresponding
lib/Alzabo/Runtime/Schema.pm view on Meta::CPAN
L<C<Alzabo::Exception::System>|Alzabo::Exceptions>
=head2 set_user ($user)
Sets the username to use when connecting to the database.
=head2 user
Return the username used by the schema when connecting to the database.
=head2 set_password ($password)
Set the password to use when connecting to the database.
=head2 password
Returns the password used by the schema when connecting to the
database.
=head2 set_host ($host)
Set the host to use when connecting to the database.
=head2 host
Returns the host used by the schema when connecting to the database.
lib/Alzabo/Runtime/Schema.pm view on Meta::CPAN
If this is true, then all SQL constructed for this schema will have
quoted identifiers (like `Table`.`column` in MySQL).
This defaults to false. Turning this on adds some overhead to all SQL
generation.
=head2 connect (%params)
Calls the L<C<Alzabo::Driver-E<gt>connect>|Alzabo::Driver/connect>
method for the driver owned by the schema. The username, password,
host, and port set for the schema will be passed to the driver, as
will any additional parameters given to this method. See the L<C<<
Alzabo::Driver->connect() method >>|Alzabo::Driver/connect> for more
details.
=head2 disconnect
Calls the L<C<< Alzabo::Driver->disconnect()
>>|Alzabo::Driver/disconnect> method for the driver owned by the
schema.
lib/Alzabo/Runtime/Schema.pm view on Meta::CPAN
=head1 USER AND PASSWORD INFORMATION
This information is never saved to disk. This means that if you're
operating in an environment where the schema object is reloaded from
disk every time it is used, such as a CGI program spanning multiple
requests, then you will have to make a new connection every time. In
a persistent environment, this is not a problem. For example, in a
mod_perl environment, you could load the schema and call the
L<C<set_user()>|Alzabo::Runtime::Schema/set_user ($user)> and
L<C<set_password()>|Alzabo::Runtime::Schema/set_password ($password)>
methods in the server startup file. Then all the mod_perl children
will inherit the schema with the user and password already set.
Otherwise you will have to provide it for each request.
You may ask why you have to go to all this trouble to deal with the
user and password information. The basic reason was that I did not
feel I could come up with a solution to this problem that was secure,
easy to configure and use, and cross-platform compatible. Rather, I
think it is best to let each user decide on a security practice with
which they feel comfortable.
In addition, there are a number of modules aimed at helping store and
use this sort of information on CPAN, including C<DBIx::Connect> and
C<AppConfig>, among others.
=head1 AUTHOR
t/03-runtime.t view on Meta::CPAN
my $config = Alzabo::Test::Utils->test_config_for($rdbms);
my $s = Alzabo::Runtime::Schema->load_from_file( name => $config->{schema_name} );
# tests setting basic parameters and connecting to RDBMS
{
eval_ok( sub { $s->set_user('foo') },
"Set user for schema to foo" );
eval_ok( sub { $s->set_password('foo') },
"Set password for schema to foo" );
eval_ok( sub { $s->set_host('foo') },
"Set host for schema to foo" );
eval_ok( sub { $s->set_port(1234) },
"Set port for schema to 1234" );
$s->$_(undef) foreach qw( set_user set_password set_host set_port );
$s->connect( Alzabo::Test::Utils->connect_params_for($rdbms) );
$s->set_referential_integrity(1);
}
{
my $dbh = $s->driver->handle;
isa_ok( $dbh, ref $s->driver->{dbh},
"Object returned by \$s->driver->handle method" );
t/lib/Alzabo/Test/Utils.pm view on Meta::CPAN
sub connect_params_for
{
my $class = shift;
my $config = $class->test_config_for( shift );
return ( map { defined $config->{$_}
? ( $_ => $config->{$_} )
: () }
qw( user password host port )
);
}
sub cleanup
{
my $class = shift;
$class->remove_schema_dir;
$class->remove_all_schemas;