📄 user.pm
字号:
# vim:ts=4 sw=4
# ----------------------------------------------------------------------------------------------------
# Name : ETL::Pequel3::User.pm
# Created : 23 May 2006
# Author : Mario Gaffiero (gaffie)
#
# Copyright 1999-2007 Mario Gaffiero.
#
# This file is part of Pequel(TM).
#
# Pequel is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# Pequel is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Pequel; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# ----------------------------------------------------------------------------------------------------
# Modification History
# When Version Who What
# ----------------------------------------------------------------------------------------------------
package ETL::Pequel3::User;
require 5.005_62;
use strict;
use warnings;
use stl;
# ----------------------------------------------------------------------------------------------------
{
package ETL::Pequel3::User; #NOTE: This is the POM (Pequel Object Model)
use base qw(Class::STL::Element);
use Class::STL::ClassMembers
qw(
err
catalogue
factories
properties
generator
doc
cat
macro_use_list
parser
parser_input
parser_output
script_filename
config
user_joins
user_tables
shared_datasets
user_datasets
user_pequels
root
all_pequels
user_sections
xml
xml_schema
getopt
),
Class::STL::ClassMembers::DataMember->new(name => 'duplicate', default => 0),
Class::STL::ClassMembers::DataMember->new(name => 'generator_type', default => 'main_program'),
Class::STL::ClassMembers::DataMember->new(name => 'pequel_name', default => 'main');
#> ETL::Pequel3::Type::DataMember::XSDAttribute->new
#> (
#> name => 'pequel_name', default => 'main', xs_type => 'NMTOKEN'
#> ),
#> ETL::Pequel3::Type::DataMember::XSDAttribute->new
#> (
#> name => 'script_filename', xs_type => 'token'
#> ),
#> ETL::Pequel3::Type::DataMember::XSDAttribute->new
#> (
#> name => 'version', xs_type => 'decimal'
#> ),
#> ETL::Pequel3::Type::DataMember::XSDAttribute->new
#> (
#> name => 'script_version', xs_type => 'decimal'
#> ),
use Class::STL::ClassMembers::Constructor;
use vars qw( $AUTOLOAD );
sub AUTOLOAD
{
my $self = shift;
(my $attr = $AUTOLOAD) =~ s/.*:://;
my $s = $self->section($attr);
return $s->select(@_);
}
sub DESTROY
{
}
sub new_extra
{
my $self = shift;
use ETL::Pequel3::Type::DataMember;
use ETL::Pequel3::Error;
$self->err(ETL::Pequel3::Error->new());
use ETL::Pequel3::Catalogue;
$self->catalogue(ETL::Pequel3::Catalogue->new());
$self->properties($self->catalogue()->properties());
use ETL::Pequel3::Type::Factory::Catalogue;
$self->factories(ETL::Pequel3::Type::Factory::Catalogue->new());
use ETL::Pequel3::GetOpt;
$self->getopt(ETL::Pequel3::GetOpt->new());
use ETL::Pequel3::Type::Macros::Array; # load array macros extension
use ETL::Pequel3::Type::Macros::Date; # load date macros extension
use ETL::Pequel3::Type::Macros::String; # load string macros extension
use ETL::Pequel3::Type::Macros::Arithmetic; # load arith macros extension
use ETL::Pequel3::Type::Macros::General; # load general macros extension
use ETL::Pequel3::Type::Section::Catalogue;
$self->user_sections(ETL::Pequel3::Type::Section::Catalogue::User->new(pequel_ref => $self));
$self->err()->user_warn(10404, "The generator type '@{[ $self->generator_type()
]}' does not exist!")
unless ($self->catalogue()->generators()->exists($self->generator_type()));
$self->user_pequels(stl::list(element_type => ref($self)));
$self->macro_use_list(stl::list(element_type => 'ETL::Pequel3::Type::Macros::Abstract'));
$self->user_datasets(ETL::Pequel3::Type::DataSet::User::Local->new());
$self->all_pequels
(
defined($self->root())
? $self->root()->all_pequels()
: stl::list(element_type => ref($self))
);
if (!$self->catalogue()->xml_parsers()->exists($self->properties()->xml_parser()))
{
$self->err()->user_warn(10402, "The XML parser type '@{[
$self->properties()->xml_parser()
]}' does not exist! -- using 'default' type instead.");
$self->properties()->xml_parser('default');
}
$self->xml($self->catalogue()->xml_parsers()->exists($self->properties()->xml_parser())
->new(POM => $self)
);
$self->xml_schema($self->catalogue()->xml_schemas()->exists($self->properties()->xml_schema())
->new(POM => $self)
);
$self->root($self) unless (defined($self->root()));
$self->getopt()->prep_options($self)
if ($self->root() == $self);
$self->config($self->user_sections()->configuration()->select()->config());
$self->getopt()->copy_config($self->config());
$self->err()->diag(1, "[@{[ $self->pequel_name() ]}] GetOpt:@{[
join(', ', map($_->long_name() . ':' . $_->data(), $self->getopt()->user()->to_array())) ]}")
if ($self->root() == $self);
#TODO: need to bring in any command line options (eg. diag)...
if (defined($self->script_filename()))
{
$self->err()->diag(1, "[@{[ $self->pequel_name() ]}] <-- " . $self->script_filename());
if ($self->script_filename() =~ /\.dump$/)
{
$self->from_hash($self->script_filename());
}
elsif ($self->script_filename() =~ /\.(xml|xpq)$/)
{
$self->from_xml($self->script_filename());
}
}
$self->script_filename($self->root() == $self ? $0 : $self->root()->script_filename())
unless (defined($self->script_filename()));
$self->err()->trace_msg(10, "[@{[ $self->pequel_name() ]}] <-- " . $self->script_filename());
}
sub select
{
my $self = shift;
if (ref($_[0]) && $_[0]->isa(ref($self)))
{
my $s;
return $s if (($s = $self->exists($_[0]->pequel_name())));
$self->user_pequels()->push_back($_[0]->clone());
}
else
{
my %p = @_;
$self->err()->user_error(10402, __PACKAGE__ . "::select() function requires 'pequel_name' parameter!")
unless (exists($p{pequel_name}));
my $s;
return $s if (($s = $self->exists($p{pequel_name})));
$self->user_pequels()->push_back($self->user_pequels()->factory(%p, root => $self->root()));
}
# TODO: not the best solution?
$self->exists($self->user_pequels()->back()->pequel_name(), $self->root()->all_pequels())
? $self->user_pequels()->back()->duplicate(1)
: $self->root()->all_pequels()->push_back($self->user_pequels()->back());
return $self->user_pequels()->back();
}
sub exists
{
my $self = shift;
my $name = shift;
my $container = @_ ? shift : $self->user_pequels();
my $s;
return $s->p_element()
if ($s = stl::find_if($container->begin(), $container->end(),
ETL::Pequel3::User::Find->new(pequel_name => $name)));
return 0;
}
sub section
{
my $self = shift;
my $sname = shift;
my $s;
$s = $self->user_sections()->exists($sname);
$self->err()->user_error(10403, "Unknown section name '$sname'!")
if (!ref($s) || $s->section_name() ne $sname);
return $s;
}
sub pequel2hash
{
my $self = shift;
return $self->xml()->xml2hash();
}
sub xml2hash
{
my $self = shift;
return $self->xml()->xml2hash();
}
sub pequel2xml
{
my $self = shift;
return $self->xml()->pequel2xml();
}
sub hash2xml
{
my $self = shift;
$self->xml()->hash2xml();
}
sub hash2pequel # recursive
{
my $self = shift;
my $hash = shift;
$self->pequel_name($$hash{'pequel_name'}) if (exists($$hash{'pequel_name'}));
$self->script_filename($$hash{'script_filename'}) if (exists($$hash{'script_filename'}));
$self->config($self->user_sections()->configuration()->select()->config());
#< $self->getopt()->prep_options($self);
$self->getopt()->copy_config($self->config());
$self->user_sections(ETL::Pequel3::Type::Section::Catalogue::User->new(pequel_ref => $self));
$self->user_pequels(stl::list(element_type => __PACKAGE__));
foreach my $n
(
map
(
$_->section_name(),
grep
(
exists($$hash{$_->section_name()}),
$self->user_sections()->to_array()
)
)
)
{
foreach my $s (ref($$hash{$n}) eq 'ARRAY' ? @{$$hash{$n}} : $$hash{$n})
{
next unless ref($s);
my $section = $self->section($n)->select(
map
(
($_, $$s{$_}),
grep($_ ne 'item', keys(%$s))
)
);
map($section->add_item(%$_), (ref($$s{item}) eq 'ARRAY' ? @{$$s{item}} : $$s{item}))
if (exists($$s{item}));
}
}
return unless (exists($$hash{'pequel'}));
foreach my $s (ref($$hash{'pequel'}) eq 'ARRAY' ? @{$$hash{'pequel'}} : $$hash{'pequel'})
{
defined($$s{'script_filename'}) && $$s{'script_filename'} =~ /\.(xml|xpq|dump)$/
? $self->select(%$s)
: $self->select(%$s)->hash2pequel($s); # recurse
}
}
sub to_xml
{
my $self = shift;
my $filename = $self->xml()->writefile(@_);
$self->err()->diag(1, "-->XML saved in $filename");
return $filename;
}
sub from_xml
{
my $self = shift;
my $filename = $self->xml()->readfile(@_);
$self->err()->diag(1, "<--XML read from $filename");
return $filename;
}
sub hash_print
{
use Data::Dumper;
my $self = shift;
$Data::Dumper::Indent = 1;
return Dumper($self->pequel2hash());
}
sub to_hash
{
my $self = shift;
my $filename = shift || do {
$self->config()->prefix()
. '/'
. (split(/[\/]+/, $self->script_filename()))[-1]
. ".dump"
};
open(DUMP, ">$filename");
print DUMP $self->hash_print();
close(DUMP);
$self->err()->diag(1, "-->HASH dump saved in $filename");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -