Genezzo
view release on metacpan or search on metacpan
lib/Genezzo/Dict.pm view on Meta::CPAN
return $stat;
}
# make all your functions, whether exported or not;
# private
sub _init
{
my $self = shift;
my %optional = (
init_db => 0, # initialize the database
force_init_db => 0, # blow away existing db
name => "default",
dbsize => $Genezzo::Util::DEFDBSIZE,
blocksize => $Genezzo::Util::DEFBLOCKSIZE,
use_havok => 1 # use havok if available
);
my %required = (
gnz_home => "no gnz_home supplied !"
);
my %args = (%optional,
@_);
return 0
unless (Validate(\%args, \%required));
my ($msg, %earg);
$self->{gnz_home} = $args{gnz_home};
$self->{dbfile} = $args{name} . ".dbf";
# Get all command line definitions
if ((exists($args{unknown_defs}))
&& (defined($args{unknown_defs})))
{
# unknown command line definitions
$self->{unknown_defs} = $args{unknown_defs};
}
else
{
$self->{unknown_defs} = {};
}
# Get all command line file header definitions
if ((exists($args{fhdefs}))
&& (defined($args{fhdefs})))
{
# file header definitions
$self->{fhdefs} = $args{fhdefs};
}
else
{
$self->{fhdefs} = {};
}
# get all actual file header info
$self->{fileheaderinfo} = {}; # set when load SYSTEM tablespace
# get dictionary preference table info
$self->{prefs} = {};
$self->{basichelp} = Genezzo::BasicHelp->new();
# for raw filesystems we pretend /dev/raw is the home directory
# and raw1 is the file.
if($self->{gnz_home} eq "/dev/raw"){
setUseRaw(1);
}else{
setUseRaw(0);
}
if(getUseRaw()){
$self->{dbfile} = "raw1"; # need to be able to change this
}else{
$self->{dbfile} = $args{name} . ".dbf";
}
my $fhts; # gnz_home table space
if(getUseRaw()){
$fhts = $self->{gnz_home};
}else{
$fhts = File::Spec->catdir($self->{gnz_home}, "ts");
}
$self->{dbfile_full} =
File::Spec->rel2abs(
File::Spec->catfile(
$fhts,
$self->{dbfile})
);
# convert file and blocksize specifications to pure numbers
$self->{dbsize} = HumanNum(val => $args{dbsize},
name => "db file size");
$self->{blocksize} = HumanNum(val => $args{blocksize},
name => "blocksize");
if ($args{use_havok} eq "0")
{
whisper "havok is disabled";
$self->{use_havok} = 0; # disable havok
}
else
{
$self->{use_havok} = 1;
}
return 0
unless (defined($self->{dbsize})
&& defined($self->{blocksize}));
return 0
unless (NumVal(val => $self->{blocksize},
name => "blocksize",
MIN => $Genezzo::Util::MINBLOCKSIZE,
MAX => $Genezzo::Util::MAXBLOCKSIZE));
return 0
unless (NumVal(val => $self->{dbsize},
lib/Genezzo/Dict.pm view on Meta::CPAN
sub _get_tsid_by_name
{
my $self = shift;
my $tsname = shift;
return undef
unless (defined($tsname));
if ($tsname eq 'SYSTEM')
{
return 1; # easy peasy: SYSTEM is tablespace # 1
}
my $sql = 'select tsid from _tspace where tsname = \'' .
$tsname . '\'';
my $sth = $self->_sql_execute(sql_statement => $sql);
return undef
unless (defined($sth));
my @ggg = $sth->fetchrow_array();
return undef
unless (scalar(@ggg));
my $tsid = shift @ggg;
return $tsid;
}
sub name
{
my $self = shift;
$self->{NAME} = shift if @_ ;
return $self->{NAME};
} # end name
sub DictDump
{
my $self = shift;
my @params = @_;
# XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX
# NOTE: dumper still prints - does not use gzerr!!
# XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX
if ((0 == scalar (@params)) || ($params[0] =~ m/ALL/i))
{
print Dumper(%{ $self->{dict_tables}}), "\n";
}
elsif ($params[0] =~ m/help/i)
{
my %legitdefs = (
all => "dump dictionary table structs",
help => "this message",
table => "names of dictionary tables",
ts => "dump tablespace structs (very long)",
tstab => "dump loaded tablespace tables (short)",
prefs => "startup prefs",
bc => "buffer cache (per tablespace)",
tsidx => "tablespace index information",
files => "file headers and extent info"
);
print "\n";
while (my ($kk, $vv) = each (%legitdefs))
{
print "$kk:\t$vv\n";
}
print "\n";
}
elsif ($params[0] =~ m/TABLE/i)
{
if (exists ($self->{dict_tables}))
{
my $tcount = 0;
foreach my $kk (sort (keys %{$self->{dict_tables}} ))
{
$tcount++;
print "$kk \n";
}
print "\n$tcount tables\n";
}
else
{
print "no tables ! \n";
}
}
elsif ($params[0] =~ m/^TS$/i)
{
print Dumper($self->{tablespaces});
}
elsif ($params[0] =~ m/^TSTAB/i) # dump each ts object separately
{
while (my ($kk, $vv) = each (%{$self->{tablespaces}}))
{
print "tablespace: $kk\n";
# print Dumper($vv->{tsref});
for my $jj (keys(%{$vv}))
{
print " $jj\n";
if ($jj eq 'table_cache')
{
for my $tt (keys(%{$vv->{table_cache}}))
{
print " $tt\n";
}
}
}
}
}
elsif ($params[0] =~ m/^PREF/i) # dump prefs
{
print Dumper($self->{prefs});
print Dumper($self->{fileheaderinfo});
print Dumper($self->{unknown_defs});
print Dumper($self->{fhdefs});
}
elsif ($params[0] =~ m/^BC/i) # dump buffer cache
{
while (my ($kk, $vv) = each (%{$self->{tablespaces}}))
{
print "tablespace: $kk\n";
my $bc1;
if (exists($vv->{tsref})
&& exists($vv->{tsref}->{the_ts})
&& exists($vv->{tsref}->{the_ts}->{bc}))
{
$bc1 = $vv->{tsref}->{the_ts}->{bc};
my $h1 = $bc1->Dump();
print Dumper($h1)
if (defined($h1));
}
}
}
elsif ($params[0] =~ m/^tsidx/i) # dump tablespace index information
{
print "ts_tsid\t", Dumper($self->{ts_tsid_idx});
print "afu_tid\t", Dumper($self->{afu_tid_idx});
print "tsf_fid\t", Dumper($self->{tsf_fid_idx});
}
elsif ($params[0] =~ m/^files/i) # dump block zero information
{
my $tsf = $self->_get_table(tname => "_tsfiles");
return 0
unless (defined($tsf));
return 0
unless (exists($self->{tablespaces}->{SYSTEM}));
my $ts1 = $self->{tablespaces}->{SYSTEM};
return 0
unless (exists($ts1->{tsref})
&& exists($ts1->{tsref}->{the_ts})
&& exists($ts1->{tsref}->{the_ts}->{bc}));
my $bc1 = $ts1->{tsref}->{the_ts}->{bc};
while (my ($kk, $vv) = each (%{$tsf}))
{
my $getcol = $corecolnum{"_tsfiles"};
my $fsize = $vv->[$getcol->{filesize}];
my $blksize = $vv->[$getcol->{blocksize}];
my $filenum = $vv->[$getcol->{fileidx}];
my $numblks = $vv->[$getcol->{numblocks}];
my $fhts; # gnz_home table space
if(getUseRaw()){
$fhts = $self->{gnz_home};
lib/Genezzo/Dict.pm view on Meta::CPAN
my %required = (
);
my %args = (
@_);
# tablespace, tname
greet (%args);
# return 0
# unless (Validate(\%args, \%required));
return 1
unless ($self->{started});
$self->{started} = 0;
$self->{use_constraints} = 0;
return ($self->doDictPreLoad ());
}
# private
sub _DictDBDefineTable
{
my ($self, $inhash) = @_;
while (my ($kk, $vv) = each (%{$inhash}))
{
my %coldatatype;
my $colidx;
my @coldefs = split(' ', $vv);
%coldatatype = ();
$colidx = 1;
foreach my $col (@coldefs)
{
my ($colname, $dtype) = split('=', $col);
$coldatatype{$colname} = [$colidx, $dtype];
$colidx++;
}
return 0
unless $self->DictTableCreate (tname => $kk,
tabdef => \%coldatatype,
tablespace => "SYSTEM",
);
}
return 1;
}
#private
sub _DictDefineCoreTabs
{
my ($self, $tsname, $deffile, $deffilsize, $makepref1, $hdrsize) = @_;
# if makepref1 is set, build the preferences table, else use the
# existing one in default.dbf
if ($makepref1)
{
my %basicprefs = (
blocksize => $self->{blocksize},
home => $self->{gnz_home},
default_file => $deffile,
bc_size => 40,
automount => "TRUE", # "FALSE",
genezzo_version => $Genezzo::GenDBI::VERSION,
export_start_tid => 1
);
whisper "create _pref1...\n";
my $tablename = "_pref1";
my $ptable = $self->_get_table(tname => $tablename,
object_id => $coretid{$tablename},
tablespace => $tsname);
my $realtie = tied(%{$ptable});
# ct _pref1 name=c value=c creationdate=c
my $rowarr = [
"pref_key",
"pref_value",
time_iso8601(), # creationdate
"init"
];
my $getcol = $corecolnum{"_pref1"};
while (my ($kk, $vv) = each (%basicprefs))
{
$rowarr->[$getcol->{pref_key}] = $kk;
$rowarr->[$getcol->{pref_value}] = $vv;
unless (defined($realtie->HPush($rowarr)))
{
my $msg = "Failed to create table $tablename";
my %earg = (self => $self, msg => $msg, severity => 'fatal');
&$GZERR(%earg)
if (defined($GZERR));
return 0;
}
}
if (exists($self->{unknown_defs}))
{
$rowarr->[$getcol->{pref_desc}] = "init - unknown";
while (my ($kk, $vv) = each (%{$self->{unknown_defs}}))
{
$rowarr->[$getcol->{pref_key}] = $kk;
$rowarr->[$getcol->{pref_value}] = $vv;
unless (defined($realtie->HPush($rowarr)))
{
my $msg = "Failed to create table $tablename";
my %earg = (self => $self, msg => $msg,
severity => 'fatal');
&$GZERR(%earg)
if (defined($GZERR));
return 0;
}
}
}
}
# create _tspace
{
whisper "create _tspace...\n";
my $tablename = "_tspace";
# XXX XXX XXX: get the tablespace blocksize!!
my $blocksize = $self->{blocksize};
my $tstable = $self->_get_table(tname => $tablename,
object_id => $coretid{$tablename},
tablespace => $tsname);
# ct _tspace tsid=n tsname=c creationdate=c
my $rowarr = [
1, # first tablespace
$tsname, # tablespace name
time_iso8601(), # creationdate
$blocksize
];
my $realtie = tied(%{$tstable});
unless (defined($realtie->HPush($rowarr)))
{
my $msg = "Failed to create table $tablename";
lib/Genezzo/Dict.pm view on Meta::CPAN
&$GZERR(%earg)
if (defined($GZERR));
return 0;
}
$colidx++;
}
}
}
return 1;
}
#private
sub _DictDBInit
{
my $self = shift;
# don't need to init if dict file exists
my $deffile = $self->{dbfile};
my $deffile_full = $self->{dbfile_full};
# XXX: Add FORCE for recreate...
if (-e $deffile_full && !getUseRaw())
{
my $msg = "file $deffile_full already exists\n";
my %earg = (self => $self, msg => $msg,
severity => 'warn');
&$GZERR(%earg)
if (defined($GZERR));
return 0;
}
my $tshref = $self->{tablespaces};
my $tsname = "SYSTEM";
# load the tablespace object
return 0
if (exists ($tshref->{$tsname}));
{
use POSIX ; # need some rounding
$self->{blocksize} = POSIX::floor($self->{blocksize});
$self->{dbsize} = POSIX::floor($self->{dbsize});
# Note: number of blocks must be an integer -- true dbsize
# gets calculated in TSAddfile
}
my $ts1 = Genezzo::Tablespace->new(name => $tsname,
tsid => 1,
gnz_home => $self->{gnz_home},
blocksize => $self->{blocksize},
bc_size => $self->{prefs}->{bc_size},
GZERR => $self->{GZERR},
dict => $self);
$tshref->{$tsname} = {
tsref => $ts1,
};
my %af_args = (filename => $deffile,
filesize => $self->{dbsize});
if (exists($self->{fhdefs}))
{
# optional file header definitions
$af_args{defs} = $self->{fhdefs};
}
my @fstat = $ts1->TSAddFile(%af_args);
return 0
unless (scalar(@fstat));
my $fileidx = $fstat[0];
$self->{dbsize} = $fstat[1];
$self->{headersize} = $fstat[2];
my $deffilsize = $self->{dbsize};
$ts1->TSSave();
# NOTE: clear out the tablespace info to force a
# clean tablespace reload from _get_table.
$ts1 = ();
delete $tshref->{$tsname};
# define all the core tables, including pref1
return $self->_DictDefineCoreTabs($tsname, $deffile, $deffilsize, 1,
$self->{headersize});
} # end dictdbinit
sub DictSave
{
my $self = shift;
unless ($self->{started})
{
greet "dict not started";
return 0;
}
while (my ($kk, $vv) = each (%{$self->{tablespaces}}))
{
whisper "tablespace: $kk\n";
next unless (exists($vv->{tsref}));
my $ts1 = $vv->{tsref};
$ts1->TSSave(@_);
my $msg = "saved tablespace $kk\n";
my %earg = (self => $self, msg => $msg,
severity => 'info');
lib/Genezzo/Dict.pm view on Meta::CPAN
} # end dictsave
sub DictRollback
{
my $self = shift;
unless ($self->{started})
{
greet "dict not started";
return 0;
}
my $sys_ts = undef;
while (my ($kk, $vv) = each (%{$self->{tablespaces}}))
{
whisper "tablespace: $kk\n";
next unless (exists($vv->{tsref}));
my $ts1 = $vv->{tsref};
$sys_ts = $ts1
if ($kk =~/^SYSTEM$/); # need to reload system tablespace
$ts1->TSRollback(@_);
greet $kk;
# greet $self->_reloadTS($kk);
$vv->{table_cache} = {}; # XXX XXX: blow out the table cache
# to force reload
my $msg = "rollback tablespace $kk\n";
my %earg = (self => $self, msg => $msg,
severity => 'info');
&$GZERR(%earg)
if (defined($GZERR));
}
if (defined($sys_ts))
{
# XXX XXX: somewhat abusive - rollback to SYSTEM requires a
# reload of the entire dictionary
$self->{started} = 0;
$self->{use_constraints} = 0; # Note: need to shutoff constraints
# before startup
return $self->DictStartup();
}
return 1;
} # end dictrollback
sub doDictPreLoad
{
my $self = shift;
whisper "load prefs...\n";
my $tsname = "SYSTEM";
my $deffile = $self->{dbfile};
my $deffilsize = $self->{dbsize};
my $tshref = $self->{tablespaces};
# NOTE: clear out the tablespace info to force a
# clean tablespace reload from _get_table.
if (exists( $tshref->{$tsname}))
{
delete $tshref->{$tsname};
}
# whisper "preload start";
$self->{preload} = 1;
return 0 # define all the core tables *except* pref1
unless $self->_DictDefineCoreTabs($tsname, $deffile,
$deffilsize, 0,
$self->{headersize});
return 0
unless ($self->_loadDictMemStructs ());
# print Dumper(%{ $self->{dict_tables}}), "\n";
return 0
unless ($self->_TSForceFile1("SYSTEM", "_pref1"));
# XXX XXX: create a hash of methods associated with pref1, use the
# key/val pairs to reset system preferences
$self->{prefs} = {};
my $hashi = $self->_get_table (tname => '_pref1') ;
# XXX XXX: replace with filter and SQLFetch...
while ( my ($kk, $vv) = each ( %{$hashi}))
{
my $getcol = $corecolnum{"_pref1"};
my $pref_key = $vv->[$getcol->{pref_key}];
my $pref_val = $vv->[$getcol->{pref_value}];
$self->{prefs}->{$pref_key} = $pref_val;
if ($pref_key =~ m/bc_size/)
{
my $tshref = $self->{tablespaces};
my $tsname = 'SYSTEM';
my $ts1 = $tshref->{$tsname}->{tsref};
# greet $pref_val;
my $bufsz = $ts1->{the_ts}->{bc}->Resize($pref_val);
if ($pref_val ne $bufsz)
{
my $msg = "reset buffer cache to $bufsz from $pref_val";
my %earg = (self => $self, msg => $msg,
severity => 'info');
&$GZERR(%earg)
if (defined($GZERR));
}
# last; # XXX XXX : need to reset pref1 hash to start at beginning
}
}
$self->{preload} = 0;
# whisper "preload end";
return 1;
}
#private
sub _TSForceFile1
{
my ($self, $tsname, $tablename) = @_;
return 0
unless (defined($tsname));
return 0
unless (exists($self->{tablespaces}));
return 0
unless (exists($self->{tablespaces}->{$tsname}));
my $ts1 = $self->{tablespaces}->{$tsname}->{tsref};
return 0
unless (defined($ts1));
# force the table to use file 1, i.e.
#
# $ts1->{tabsp_tables}->{$tablename}->{desc} = { filesused => [1] };
#
return ($ts1->TSForceFile(tablename => $tablename, filenumber => 1 ));
}
#private
sub _reloadTS
{
my ($self, $tsname) = @_;
return 0
lib/Genezzo/Dict.pm view on Meta::CPAN
# loads ts and table objects (if necessary) and returns the table tied hash
sub _get_table
{
my $self = shift;
my %required = (
%req_tname,
tablespace => "no tablespace !"
);
# in the normal case the table is stored to disk, but may use
# in-memory tables during preload.
my %optional = (
TableHashType => "DISK", # store table on disk
object_type => "TABLE",
tablespace => "SYSTEM", # make easier for system tabs
dbh_ctx => {}
);
my %args = (
%optional,
@_);
# tablespace, tname
# greet (%args);
return undef
unless (Validate(\%args, \%required));
my $tsname = $args{tablespace};
my $tshref = $self->{tablespaces};
my $tablename = $args{tname};
# unless (defined($tsname))
# {
# use Carp;
# greet $self->{dict_tables};
# croak "agh";
# }
# load the tablespace object
unless (exists ($tshref->{$tsname}))
{
# NOTE: INIT if first load via SYSTEM tablespace
my $init = ($tsname eq 'SYSTEM');
my $tsid = $self->_get_tsid_by_name($tsname);
unless (defined($tsid))
{
whisper "no tsid!";
return undef;
}
my %tspace_args = (name => $tsname,
tsid => $tsid,
gnz_home => $self->{gnz_home},
blocksize => $self->{blocksize},
GZERR => $self->{GZERR},
dict => $self);
if (exists($self->{prefs})
&& exists($self->{prefs}->{bc_size}))
{
# set the buffer cache size if prefs are loaded
$tspace_args{bc_size} = $self->{prefs}->{bc_size}
}
my $ts1 = Genezzo::Tablespace->new(%tspace_args);
# XXX: need to perform special initialization for SYSTEM
# tablespace that only loads the core tables. dodictload will
# reload tablespace using dictionary tables after core dict
# tables are loaded. clear as mud.
my $loadtype = "NORMAL";
if ($init)
{
if ($self->{preload})
{
$loadtype = "PRELOAD";
}
else
{
$loadtype = "INIT";
}
}
unless ($ts1->TSLoad(loadtype => $loadtype))
{
whisper "load failed";
return undef;
}
$tshref->{$tsname} = {
tsref => $ts1, # tablespace object reference
table_cache => {} # cache of bound table hashes
};
}
# XXX XXX : add support for filter? don't cache filtered tables?
# load the table tied hash
unless (exists ($tshref->{$tsname}->{table_cache}->{$tablename}))
{
my $ts1 = $tshref->{$tsname}->{tsref};
my %thargs = (tname => $tablename,
htype => $args{TableHashType},
object_type => $args{object_type},
dbh_ctx => $args{dbh_ctx}
);
if (defined($args{object_id}))
{
$thargs{object_id} = $args{object_id};
}
else
{ # fixup for core tables - get their tids from coretid
if (exists($coretid{$tablename}))
{
$thargs{object_id} = $coretid{$tablename};
}
else
{
whisper "no object id for $tablename";
lib/Genezzo/Dict.pm view on Meta::CPAN
}
else
{
# use default dbf file
my $fhts; # gnz_home table space
if(getUseRaw()){
$fhts = $self->{gnz_home};
}else{
$fhts = File::Spec->catdir($self->{gnz_home}, "ts");
}
$filename = File::Spec->catdir($fhts, $self->{dbfile});
}
return undef
unless (
exists($self->{tablespaces}->{$tsname})
&& exists($self->{tablespaces}->{$tsname}->{tsref}));
my $tsref = $self->{tablespaces}->{$tsname}->{tsref};
return undef
unless (exists($tsref->{the_ts})
&& exists($tsref->{the_ts}->{bc}));
my $bc1 = $tsref->{the_ts}->{bc};
my $file_info = $bc1->BCFileInfoByName(FileName => $filename);
return undef
unless (defined($file_info));
my $foo = $bc1->FileSetHeaderInfoByName(FileName => $filename,
newkey => $newkey,
newval => $newval);
if (defined($foo))
{
# XXX XXX: should reload fileheader_info if updated SYSTEM
# default datafile
}
return $foo;
} # end DictSetFileInfo
sub _dict_ts_guts
{
my $self = shift;
my ($tsname , $tsid, $blocksize) = @_;
my $ts1;
{
my $tshref = $self->{tablespaces};
my %tspace_args = (name => $tsname,
tsid => $tsid,
gnz_home => $self->{gnz_home},
blocksize => $blocksize,
GZERR => $self->{GZERR},
dict => $self);
if (exists($self->{prefs})
&& exists($self->{prefs}->{bc_size}))
{
# set the buffer cache size if prefs are loaded
$tspace_args{bc_size} = $self->{prefs}->{bc_size}
}
$ts1 = Genezzo::Tablespace->new(%tspace_args);
unless ($ts1->TSLoad(loadtype => "NORMAL"))
{
whisper "load failed";
return undef;
}
$tshref->{$tsname} = {
tsref => $ts1, # tablespace object reference
table_cache => {} # cache of bound table hashes
};
}
return $ts1;
}
sub DictTSpaceCreate
{
my $self = shift;
my %required = (
tablespace => "no tablespace !"
);
my %optional = (
blocksize => $self->{blocksize},
dbh_ctx => {}
);
my %args = (
%optional,
@_);
# tablespace
# greet (%args);
return 0
unless (Validate(\%args, \%required));
unless ($self->{started} || $self->{preload} )
{
my %earg = (self => $self, msg => "dict not started\n",
severity => 'warn');
&$GZERR(%earg)
if (defined($GZERR));
return 0;
}
my $tsname = $args{tablespace};
# insert the tablespace
my $tsid = $self->_get_tsid_by_name($tsname);
if (defined($tsid))
( run in 0.489 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )