📄 table.pm
字号:
# vim:ts=4 sw=4
# ----------------------------------------------------------------------------------------------------
# Name : ETL::Pequel3::Type::Table.pm
# Created : 2 June 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::Type::Table;
require 5.005_62;
use strict;
use warnings;
use ETL::Pequel3::CodeStyler;
# ----------------------------------------------------------------------------------------------------
{
package ETL::Pequel3::Type::Table::Abstract;
use base qw(Class::STL::Element);
use Class::STL::ClassMembers
qw(
catalogue
err
properties
pequel_types
sorters
table_number
fields
tname
field_map
key_field
verify
configuration
used_by_list
use_list
package_name
load_function_name
load_name
pequel_ref
name
description
),
Class::STL::ClassMembers::DataMember->new(name => 'xs_type', default => 'NMTOKEN'),
Class::STL::ClassMembers::DataMember->new(name => 'fieldset_type', default => 'table_fields'),
Class::STL::ClassMembers::DataMember->new(name => 'key_type', default => 'string'); #??? not used ???
use Class::STL::ClassMembers::Constructor;
use ETL::Pequel3::Error;
sub new_extra
{
my $self = shift;
use ETL::Pequel3::Catalogue;
$self->catalogue(ETL::Pequel3::Catalogue->new());
$self->err(ETL::Pequel3::Error->new());
$self->properties(ETL::Pequel3::Type::Properties->new());
defined($self->pequel_ref()->config())
? $self->configuration($self->pequel_ref()->config())
: $self->configuration(ETL::Pequel3::Type::Properties::User->new());
$self->pequel_types(ETL::Pequel3::Type::PequelTypes::Catalogue->new());
$self->sorters(ETL::Pequel3::Type::Sorters::Catalogue->new());
$self->tname('_T_' . $self->name());
use ETL::Pequel3::Type::FieldSet;
$self->fields($self->catalogue()->fieldsets()->exists($self->fieldset_type())
->new(table => $self, pequel_ref => $self->pequel_ref()));
$self->used_by_list(stl::list());
$self->use_list(stl::list());
$self->package_name(ref($self));
$self->load_function_name("load@{[ $self->tname() ]}");
$self->load_name($self->package_name() . '::' . $self->load_function_name());
return $self;
}
sub factory
{
my $self = shift;
my %p = @_; # table_type, static, input_dataset, dataset_spec, ...
return $self->new(%p);
}
sub prepare
{
my $self = shift;
my $items = shift;
}
sub code_load_table
{
# virtual function
}
sub code_start
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
$c->code("our \$@{[ $self->tname() ]} =");
$c->over();
$c->code("\&@{[ $self->load_name() ]}();");
$c->code("# ref to \%@{[ $self->tname() ]} hash");
$c->back();
return $c;
}
sub translate
{
my $self = shift;
my $key_exp = shift;
my $field = shift; # || undef;
my $show_synonyms = shift;
my $target_obj = shift; #TODO: not best solution?
my $c = ETL::Pequel3::CodeStyler::Program::Perl->new();
if (defined($field) && !ref($field))
{
$field =~ s/^@{[ $self->name() ]}->//;
my $f = $self->fields()->exists($field);
$self->err()->user_error(10302, "Unknown field '$field' for table '@{[ $self->name() ]}'")
unless (defined($f) && ref($f));
$field = $f;
}
if (defined($field))
{
#> $c->code($field->getvar($key_exp, $show_synonyms, $target_obj)); # update ref's to key-fields
$c->code($field->getvar($key_exp, $show_synonyms));
$target_obj->xref()->references($field) if (defined($target_obj) && $target_obj->can('xref'));
$field->xref()->referenced_by($target_obj) if (defined($target_obj) && $field->can('xref'));
}
else
{
# !! this should never happen -- a field name is required !!
# keyfld can be an expression eg: another macro
my $key_eval = $key_exp =~ /[&\(|\[|,]/ ? "\@{[ $key_exp ]}" : $key_exp;
$c->code('$$' . $self->tname() . '{qq{' . $key_eval . '}}');
}
return $c;
}
sub code_display_info
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
my $extra = shift;
$c->comment("++++++ Table @{[ $self->name() ]} --> Type @{[ ref($self) ]} ++++++");
$c->comment("++++++ $extra") if (defined($extra));
return $c;
}
sub attach_sorter #--> External::Abstract ?? --> move to dataset
{
my $self = shift;
my $key_type = shift;
# TODO:Need to verify key_field exists!
$self->input_dataset()->datasource()->sorter(
$self->sorters()->exists($self->properties()->sorter())->new(
uniq => 1,
field_delimiter => $self->input_dataset()->can('field_delimiter')
? $self->input_dataset()->field_delimiter() : undef,
pequel_ref => $self->pequel_ref()
)
);
#< # TODO: dataset-type to determine sorter: eg packed type no sorter...
$self->input_dataset()->datasource()->sorter()->add(
name => $self->key_field(),
column => $self->fields()->exists($self->key_field())->ds_column(),
pequel_type => $key_type,
pequel_ref => $self->pequel_ref(),
);
}
}
# ----------------------------------------------------------------------------------------------------
{
package ETL::Pequel3::Type::Table::Local::Data;
use base qw(Class::STL::Element);
use Class::STL::ClassMembers qw( key value );
use Class::STL::ClassMembers::Constructor;
sub new_extra
{
my $self = shift;
$self->value([]) unless defined($self->value());
return $self;
}
}
# ----------------------------------------------------------------------------------------------------
{
package ETL::Pequel3::Type::Table::Local;
use base qw(ETL::Pequel3::Type::Table::Abstract);
use Class::STL::ClassMembers qw( data ),
Class::STL::ClassMembers::DataMember->new(name => 'description', default => "The F<local> table type can be used to create a table with the data declared within the I<pequel script>. The table data is declared within the I<items> with the F<key>, F<value> attribute pairs. The F<value> attribute consists of string of space delimited data values"),
Class::STL::ClassMembers::DataMember->new(name => 'name', default => 'local');
use Class::STL::ClassMembers::Constructor;
sub new_extra
{
my $self = shift;
$self->data(stl::list(element_type => 'ETL::Pequel3::Type::Table::Local::Data'));
return $self;
}
sub factory
{
my $self = shift;
my %p = @_; # table_type, static, input_dataset, dataset_spec, ...
return $p{table_type} eq 'local' ? $self->new(%p) : 0;
}
sub code_load_table
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
return if ($c->jump("load@{[ $self->tname() ]}")); # ???
$c->divider();
$self->code_display_info($c, "@{[ __PACKAGE__ ]}");
$c->open_block("{");
$c->code("package " . $self->package_name() . ";");
$c->code("sub @{[ $self->load_function_name() ]}");
$c->open_block("{");
$c->code("my \%@{[ $self->tname() ]} =");
$c->code("(");
$c->over();
my $count=0;
foreach my $d (sort { $a->key() cmp $b->key() } $self->data()->to_array())
{
$c->newline_on();
$c->indent_off();
$c->code(',') if (++$count > 1);
$c->indent_on();
$c->newline_off();
$c->code("'@{[ $d->key() ]}' => ");
($self->fields()->size() == 0)
? $c->code("'@{[ $d->key() ]}'")
: ($self->fields()->size() == 1)
? $c->code("'@{[ ${$d->value()}[0] ]}'")
: $c->code("['@{[ join(q{', '}, map($_, map(defined($_) ? $_ : '', @{$d->value()}))) ]}']");
}
$c->newline_on();
$c->code("");
$c->back();
$c->code(");");
$c->code('return \%' . $self->tname() . ';');
$c->close_block();
$c->close_block();
return $c;
}
sub prepare
{
my $self = shift;
my $items = shift;
$self->fields()->map_fields($self->field_map());
# Copy the data:
foreach (grep(defined($_->key_value()), $items->to_array())) {
$self->data()->push_back($self->data()->factory(
key => $_->key_value(),
value => $_->data_values()
));
}
}
}
# ----------------------------------------------------------------------------------------------------
{
package ETL::Pequel3::Type::Table::External::Abstract;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -