package Rose::DB::Registry::Entry; use strict; use Clone::PP(); use Rose::Object; our @ISA = qw(Rose::Object); our $VERSION = '0.784'; our $Debug = 0; # # Object data # our %Attrs; BEGIN { our %Attrs = ( # Generic catalog => { type => 'scalar' }, database => { type => 'scalar' }, dbi_driver => { type => 'scalar' }, description => { type => 'scalar' }, domain => { type => 'scalar' }, driver => { type => 'scalar', make_method => 0 }, dsn => { type => 'scalar' }, host => { type => 'scalar' }, password => { type => 'scalar' }, port => { type => 'scalar' }, schema => { type => 'scalar' }, server_time_zone => { type => 'scalar' }, type => { type => 'scalar' }, username => { type => 'scalar' }, connect_options => { type => 'hash', method_spec => { interface => 'get_set_init' } }, pre_disconnect_sql => { type => 'array' }, post_connect_sql => { type => 'array' }, # Oracle service => { type => 'scalar' }, # Pg european_dates => { type => 'boolean', method_spec => { default => 0 } }, pg_enable_utf8 => { type => 'boolean' }, options => { type => 'scalar' }, service => { type => 'scalar' }, sslmode => { type => 'scalar' }, # SQLite auto_create => { type => 'boolean', method_spec => { default => 1 } }, sqlite_unicode => { type => 'boolean' }, # MySQL mysql_auto_reconnect => { type => 'boolean' }, mysql_client_found_rows => { type => 'boolean' }, mysql_compression => { type => 'boolean' }, mysql_connect_timeout => { type => 'boolean' }, mysql_embedded_groups => { type => 'scalar' }, mysql_embedded_options => { type => 'scalar' }, mysql_enable_utf8 => { type => 'boolean' }, mysql_enable_utf8mb4 => { type => 'boolean' }, mysql_local_infile => { type => 'scalar' }, mysql_multi_statements => { type => 'boolean' }, mysql_read_default_file => { type => 'scalar' }, mysql_read_default_group => { type => 'scalar' }, mysql_socket => { type => 'scalar' }, mysql_ssl => { type => 'boolean' }, mysql_ssl_ca_file => { type => 'scalar' }, mysql_ssl_ca_path => { type => 'scalar' }, mysql_ssl_cipher => { type => 'scalar' }, mysql_ssl_client_cert => { type => 'scalar' }, mysql_ssl_client_key => { type => 'scalar' }, mysql_use_result => { type => 'boolean' }, mysql_bind_type_guessing => { type => 'boolean' }, ); } sub _attrs { my(%args) = @_; my $type = $args{'type'}; # Type filter first my @attrs = $type ? (grep { $Attrs{$_}{'type'} eq $type } keys(%Attrs)) : keys(%Attrs); if($args{'with_defaults'}) { @attrs = grep { $Attrs{$_}{'method_spec'} && defined $Attrs{$_}{'method_spec'}{'default'} } @attrs; } elsif($args{'no_defaults'}) { @attrs = grep { !$Attrs{$_}{'method_spec'} || !defined $Attrs{$_}{'method_spec'}{'default'} } @attrs; } return wantarray ? @attrs : \@attrs; } sub _attr_method_specs { my $attrs = _attrs(@_); my @specs; foreach my $attr (@$attrs) { next if(exists $Attrs{$attr}{'make_method'} && !$Attrs{$attr}{'make_method'}); if(my $spec = $Attrs{$attr}{'method_spec'}) { push(@specs, $attr => $spec); } else { push(@specs, $attr); } } return wantarray ? @specs : \@specs; } use Rose::Object::MakeMethods::Generic ( 'scalar' => [ _attr_method_specs(type => 'scalar'), ], 'boolean' => [ _attr_method_specs(type => 'boolean'), ], 'hash' => [ _attr_method_specs(type => 'hash'), 'connect_option' => { hash_key => 'connect_options' }, ], 'array' => [ _attr_method_specs(type => 'array'), ] ); sub init_connect_options { {} } sub autocommit { shift->connect_option('AutoCommit', @_) } sub print_error { shift->connect_option('PrintError', @_) } sub raise_error { shift->connect_option('RaiseError', @_) } sub handle_error { shift->connect_option('HandleError', @_) } sub driver { my($self) = shift; return $self->{'driver'} unless(@_); $self->{'dbi_driver'} = shift; return $self->{'driver'} = lc $self->{'dbi_driver'}; } sub dump { my($self) = shift; my %dump; foreach my $attr (_attrs(type => 'scalar'), _attrs(type => 'boolean', no_defaults => 1)) { my $value = $self->$attr(); next unless(defined $value); $dump{$attr} = $value; } foreach my $attr (_attrs(type => 'hash'), _attrs(type => 'array')) { my $value = $self->$attr(); next unless(defined $value); $dump{$attr} = Clone::PP::clone($value); } # These booleans have defaults, but we only want the ones # where the values were explicitly set. Ugly... foreach my $attr (_attrs(type => 'boolean', with_defaults => 1)) { my $value = $self->{$attr}; next unless(defined $value); $dump{$attr} = Clone::PP::clone($value); } return \%dump; } sub clone { Clone::PP::clone($_[0]) } 1; __END__ =head1 NAME Rose::DB::Registry::Entry - Data source registry entry. =head1 SYNOPSIS use Rose::DB::Registry::Entry; $entry = Rose::DB::Registry::Entry->new( domain => 'production', type => 'main', driver => 'Pg', database => 'big_db', host => 'dbserver.acme.com', username => 'dbadmin', password => 'prodsecret', server_time_zone => 'UTC'); Rose::DB->register_db($entry); # ...or... Rose::DB->registry->add_entry($entry); ... =head1 DESCRIPTION C objects store information about a single L data source. See the L documentation for more information on data sources, and the L documentation to learn how C objects are managed. C inherits from, and follows the conventions of, L. See the L documentation for more information. =head1 CONSTRUCTOR =over 4 =item B Constructs a C object based on PARAMS, where PARAMS are name/value pairs. Any object method is a valid parameter name. =back =head1 OBJECT METHODS =head2 GENERAL =over 4 =item B Get or set the value of the "AutoCommit" connect option. =item B Get or set the database catalog name. This setting is only relevant to databases that support the concept of catalogs. =item B Returns a clone (i.e., deep copy) of the current object. =item B Get or set the connect option named NAME. Returns the current value of the connect option. =item B Get or set the options passed in a hash reference as the fourth argument to the call to Cconnect()>. See the C documentation for descriptions of the various options. If a reference to a hash is passed, it replaces the connect options hash. If a series of name/value pairs are passed, they are added to the connect options hash. Returns a reference to the hash of options in scalar context, or a list of name/value pairs in list context. =item B Get or set the database name. =item B A description of the data source. =item B Get or set the data source domain. Note that changing the C after a registry entry has been added to the registry has no affect on where the entry appears in the registry. =item B Get or set the driver name. The DRIVER argument is converted to lowercase before being set. =item B Get or set the C DSN (Data Source Name). Note that an explicitly set DSN may render some other attributes inaccurate. For example, the DSN may contain a host name that is different than the object's current C value. I recommend not setting the DSN value explicitly unless you are also willing to manually synchronize (or ignore) the corresponding object attributes. =item B Returns a reference to a hash of the entry's attributes. Only those attributes with defined values are included in the hash keys. All values are deep copies. =item B Get or set the value of the "HandleError" connect option. =item B Get or set the database server host name. =item B Get or set the database password. =item B Get or set the database server port number. =item B Get or set the SQL statements that will be run immediately before disconnecting from the database. STATEMENTS should be a list or reference to an array of SQL statements. Returns a reference to the array of SQL statements in scalar context, or a list of SQL statements in list context. =item B Get or set the SQL statements that will be run immediately after connecting to the database. STATEMENTS should be a list or reference to an array of SQL statements. Returns a reference to the array of SQL statements in scalar context, or a list of SQL statements in list context. =item B Get or set the value of the "PrintError" connect option. =item B Get or set the value of the "RaiseError" connect option. =item B Get or set the database schema name. This setting is only useful to databases that support the concept of schemas (e.g., PostgreSQL). =item B Get or set the time zone used by the database server software. TZ should be a time zone name that is understood by C. See the C documentation for acceptable values of TZ. =item B Get or set the data source type. Note that changing the C after a registry entry has been added to the registry has no affect on where the entry appears in the registry. =item B Get or set the database username. =back =head2 DRIVER-SPECIFIC ATTRIBUTES =head3 MySQL These attributes should only be used with registry entries where the L is C. =over 4 =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =back =head3 PostgreSQL These attributes should only be used with registry entries where the L is C. =over 4 =item B Get or set the boolean value that determines whether or not dates are assumed to be in european dd/mm/yyyy format. The default is to assume US mm/dd/yyyy format (because this is the default for PostgreSQL). This value will be passed to L as the value of the C parameter in the call to the constructor C. This L object is used by L to parse and format date-related column values in methods like L, L, etc. =item B Get or set the L database handle attribute. This is set directly on the L, if one exists. Otherwise, it will be set when the L is created. If no value for this attribute is defined (the default) then it will not be set when the L is created, deferring instead to whatever default value L chooses. Returns the value of this attribute in the L, if one exists, or the value that will be set when the L is next created. See the L documentation to learn more about this attribute. =item B Get or set the SSL mode of the connection. Valid values for MODE are C, C, C, and C. See the L documentation to learn more about this attribute. =back =head3 SQLite These attributes should only be used with registry entries where the L is C. =over 4 =item B Get or set a boolean value indicating whether or not a new SQLite L should be created if it does not already exist. Defaults to true. If false, and if the specified L does not exist, then a fatal error will occur when an attempt is made to L to the database. =back =head1 AUTHOR John C. Siracusa (siracusa@gmail.com) =head1 LICENSE Copyright (c) 2010 by John C. Siracusa. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.