Gtk3-Ex-DBI
view release on metacpan or search on metacpan
lib/Gtk3/Ex/DBI/Form.pm view on Meta::CPAN
sub new {
my ( $class, $req, $xml_options ) = @_;
my $self;
if ( ref $req eq "HASH" ) {
# Assemble object from request
$self = {
dbh => $$req{dbh} # A database handle
, primary_keys => $$req{primary_keys} # An array of primary keys
, sql => $$req{sql} # A hash of SQL related stuff
, widgets => $$req{widgets} # A hash of field definitions and stuff
, force_upper_case_fields => $$req{force_upper_case_fields} # Forces fieldnames to be upper-case ( set this to match upper-case glade object names )
, schema => $$req{schema} # The 'schema' to use to get column info from
, builder => $$req{builder} # The Gtk3-Builder object ... use either this or 'form', below
, read_only => $$req{read_only} || FALSE # Whether changes to the table are allowed
, apeture => $$req{apeture} || 100 # The number of records to select at a time
, on_current => $$req{on_current} # A reference to code that is run when we move to a new record
, before_query => $$req{before_query} # A reference to code that is run *before* a query is executed ( can abort the query )
, before_insert => $$req{before_insert} # A reference to code that is run *before* an insert to the in-memory recordset ( can abort )
, before_delete => $$req{before_delete} # A reference to code that is run *before* a record is deleted ( can abort the delete operation )
, before_apply => $$req{before_apply} # A reference to code that is run *before* the 'apply' method is called
, on_apply => $$req{on_apply} # A reference to code that is run *after* the 'apply' method is called
, on_delete => $$req{on_delete} # A reference to code that is run *after* the 'delete' method is called
, on_undo => $$req{on_undo} # A reference to code that is run *after* the 'undo' method is called
, on_changed => $$req{on_changed} # A reference to code that is run *every* time a managed field is changed
, on_initial_changed => $$req{on_initial_changed} # A reference to code that is run when the recordset status *initially* changes to CHANGED
, auto_apply => $$req{auto_apply} # Boolean to force all records to be applied automatically when querying, closing, etc
, calc_fields => $$req{calc_fields} # Calculated field definitions
, defaults => $$req{defaults} # Default values
, disable_find => $$req{disable_find} || FALSE # Do we build the right-click 'find' item on GtkEntrys?
, disable_full_table_find => $$req{disable_full_table_find} || FALSE # Can the user search the whole table ( sql=>{from} ) or only the current recordset?
, combos => $$req{combos} # Definitions to set up combos
, autocompletions => $$req{autocompletions} # Definitions to set up autocompletions
, data_lock_field => $$req{data_lock_field} || undef # A field to use as a data-driven lock ( positive values will lock the record )
, status_name => $$req{status_name} # The name of a field to use as the record status indicator
, spinner_name => $$req{spinner_name} # The name of a GtkSpinButton to use as the RecordSpinner
, quiet => $$req{quiet} || FALSE # A flag to silence warnings such as missing widgets
, friendly_table_name => $$req{friendly_table_name} # Table name to use when issuing GUI errors
, custom_changed_text => $$req{custom_changed_text} # Text ( including markup ) to use in GUI questions when changes need to be applied
, changed => FALSE # A flag indicating that the current record has been changed
, changelock => FALSE # Prevents the 'changed' flag from being set when we're moving records
, constructor_done => FALSE # A flag that indicates whether the new() method has completed yet
, debug => $$req{debug} || FALSE # Dump info to terminal
, skip_query => $$req{skip_query} # Don't call query() in the constructor
, dont_update_keys => $$req{dont_update_keys} # Don't include primary keys in update statements
, use_compat_filter_clause => $$req{use_compat_filter_clause} # Build brain-dead filters for DBs that don't support mult-column 'in' clauses
, widget_prefix => $$req{widget_prefix} # A string to prefix ( builder ) widget names with when searching for them
, auto_incrementing => $$req{auto_incrementing} # A flag to indicate whether we should try to poll the last inserted ID after an insert
, recordset_tools_box => $$req{recordset_tools_box} # A box to create recordset tools in ( add / insert / update / delete / undo / spinnner )
, recordset_tool_items => $$req{recordset_tool_items} # An array of item names to add to the recordset tools box
, recordset_extra_tools => $$req{recordset_extra_tools} # Extra buttons to add to the recordset tools box
};
} else {
# Assume we're loading an XML
my $xml_cfg = XML::Simple->new(
AttrIndent => TRUE, # XML formatting option - doesn't affect performance
OutputFile => $self->{xml_file},
KeyAttr => [ ] # Stops XML::Simple from squishing some data structures
);
$self = $xml_cfg->XMLin( $req );
# Attach to the libglade / builder object
$self->{builder} = $xml_options->{gtk_builder};
# Link DBI connections
$self->{dbh} = $xml_options->{connections}->{ $self->{Connection} };
foreach my $combo ( keys %{$self->{combos}} ) {
$self->{combos}->{$combo}->{alternate_dbh} = $xml_options->{connections}->{ $self->{combos}->{$combo}->{connection_name} };
}
}
if ( $Gtk3::Ex::DBI::USE_COMPAT_FILTER_CLAUSE ) {
$self->{use_compat_filter_clause} = 1;
}
# Check we've been passed enough stuff to continue ...
if ( ! $self->{dbh} ) {
croak( "Gtk3::Ex::DBI::Form constructor missing a dbh!\n" );
}
if ( ! $self->{builder} ) {
croak( "Gtk3::Ex::DBI::Form constructor missing a 'builder' ( Gtk3::Builder ) ..." );
} elsif ( ref $self->{builder} ne "Gtk3::Builder" ) {
croak( "Gtk3::Ex::DBI::Form constructor contains a 'builder' ... but it's not a Gtk3::Builder!" );
}
# TODO: complete
# Decide what class of Gtk3::Ex::DBI to construct ...
$self->{server} = $self->{dbh}->get_info( 17 );
my $dbi_manager_class = 'Gtk3::Ex::DBI';
# Some database-specific stuff
if ( $self->{server} =~ /postgres/i ) {
$dbi_manager_class = 'Gtk3::Ex::Postgres';
if ( ! $self->{search_path} ) {
if ( $self->{schema} ) {
$self->{search_path} = $self->{schema} . ",public";
} else {
$self->{search_path} = "public";
}
}
my $sth = $self->{dbh}->prepare ( "SET search_path to " . $self->{search_path} );
eval {
$sth->execute or die $self->{dbh}->errstr;
};
if ( $@ ) {
carp( "Failed to set search_path to " . $self->{search_path}
. " for a Postgres database. I'm not sure what the implications of this are. Postgres users, please report ...\n" );
}
( run in 2.650 seconds using v1.01-cache-2.11-cpan-5a3173703d6 )