⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 generator.pm

📁 普通的ETL工具
💻 PM
📖 第 1 页 / 共 5 页
字号:
# vim:ts=4 sw=4
# ----------------------------------------------------------------------------------------------------
#  Name		: ETL::Pequel3::Generator.pm
#  Created	: 19 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::Generator;
require 5.005_62;
use strict;
use warnings;
# ----------------------------------------------------------------------------------------------------
# GENERATOR TYPE
# ----------------------------------------------------------------------------------------------------
{
	package ETL::Pequel3::Generator::Abstract; 
	use base qw(Class::STL::Element);
	use stl qw(list);
	use Class::STL::ClassMembers qw( err catalogue properties generator_name main segments user_prog caller_id ),
		Class::STL::ClassMembers::DataMember->new(name => 'show_info', default => 1);
	use Class::STL::ClassMembers::Constructor;
	sub new_extra
	{
		my $self = shift;
		use ETL::Pequel3::Error;
		$self->err(ETL::Pequel3::Error->new());
		use ETL::Pequel3::Type::Properties;
		$self->properties(ETL::Pequel3::Type::Properties->new());
		use ETL::Pequel3::Catalogue;
		$self->catalogue(ETL::Pequel3::Catalogue->new());

		$self->segments(list(element_type => 'ETL::Pequel3::Generator::Segment::Abstract'));
		$self->err()->user_error(10501, "Attribute @{[ ref($self) ]}::main is undefined!")
			unless (defined($self->main()));
		$self->err()->user_error(10500, "Attribute @{[ ref($self) ]}::main->config is undefined!")
			unless (defined($self->main()->config()));
		$self->caller_id(do { my $n=$self->main()->pequel_name();$n=~s/\W+/_/g;$n }); #???

		use ETL::Pequel3::CodeStyler;
		$self->user_prog(ETL::Pequel3::CodeStyler::Program::Perl->new(
			@_, # contains 'main', other
			program_name => 
			(
				$self->properties()->exec_dir() 
				. '/' 
				. (split(/[\/]+/, $self->main()->script_filename()))[-1]
				. ".code"
			),
			print_bookmarks => $self->err()->trace_level() >= 5,
			tab_size => $self->main()->config()->tab_size(),
			tab_type => $self->main()->config()->tab_type(),
			divider_char => $self->main()->config()->divider_char(),
			divider_length => $self->main()->config()->divider_length(),
		))
		unless (defined($self->user_prog()));
		return $self;
	}
	sub build
	{
		my $self = shift;
		$self->err()->diag(1, "[@{[ $self->main()->pequel_name() ]}] generate...");
		map($_->prepare(), $self->segments()->to_array());
		$self->user_prog()->prepare();
#>		TODO:use $self-os()->getpath(...)
		mkdir("@{[ $self->properties()->exec_dir() ]}");
		$self->user_prog()->save() if ($self->err()->trace_level() >= 5);
		$self->err->trace_msg(10, "\n++++++\n@{[ $self->user_prog()->display() ]}\n+++++\n");
	}
	sub exec
	{
		my $self = shift;
		$self->user_prog()->run();
	}
}
# ----------------------------------------------------------------------------------------------------
{
	package ETL::Pequel3::Generator::MainProgram; 
	use base qw(ETL::Pequel3::Generator::Abstract);
	use Class::STL::ClassMembers
		Class::STL::ClassMembers::DataMember->new(name => 'generator_name', default => 'main_program');
	use Class::STL::ClassMembers::Constructor;
	sub new_extra
	{
		my $self = shift;
		$self->segments()->push_back(
			$self->catalogue()->code_segments()->startup()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->user_options()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->init_global()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->open_global()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->call_load_table()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->call_execute()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->close_global()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->divider()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->main_package()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->load_table()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->sub_programs()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->end_of_program()->new(@_, user_prog => $self->user_prog() ),
		);
		return $self;
	}
}
# ----------------------------------------------------------------------------------------------------
{
	package ETL::Pequel3::Generator::SubProgram; 
	use base qw(ETL::Pequel3::Generator::Abstract);
	use Class::STL::ClassMembers
		Class::STL::ClassMembers::DataMember->new(name => 'generator_name', default => 'sub_program');
	use Class::STL::ClassMembers::Constructor;
	sub new_extra
	{
		my $self = shift;
		$self->segments()->push_back(
			$self->catalogue()->code_segments()->main_package()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->sub_programs()->new(@_, user_prog => $self->user_prog() ),
		);
		return $self;
	}
}
# ----------------------------------------------------------------------------------------------------
{
	package ETL::Pequel3::Generator::TableLoader; 
	use base qw(ETL::Pequel3::Generator::Abstract);
	use Class::STL::ClassMembers
		Class::STL::ClassMembers::DataMember->new(name => 'generator_name', default => 'table_loader');
	use Class::STL::ClassMembers::Constructor;
	sub new_extra
	{
		my $self = shift;
		$self->segments()->push_back(
			$self->catalogue()->code_segments()->startup()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->user_options()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->header_info()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->load_table()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->sub_programs()->new(@_, user_prog => $self->user_prog() ),
			$self->catalogue()->code_segments()->end_of_program()->new(@_, user_prog => $self->user_prog() ),
		);
		return $self;
	}
}
# ----------------------------------------------------------------------------------------------------
# GENERATOR TYPE CATALOGUE
# ----------------------------------------------------------------------------------------------------
{
	package ETL::Pequel3::Generator::Catalogue;
	use base qw(ETL::Pequel3::Type::Catalogue);
	use Class::STL::ClassMembers
		Class::STL::ClassMembers::DataMember->new(name => 'catalogue_name', default => 'generators'),
		Class::STL::ClassMembers::DataMember->new(name => 'target_mem_name', default => 'generator_name'),
		Class::STL::ClassMembers::DataMember->new(name => 'element_type', default => 'ETL::Pequel3::Generator::Abstract');
	use Class::STL::ClassMembers::SingletonConstructor;
	sub new_extra
	{
		my $self = shift;
		$self->push_back(
			ETL::Pequel3::Generator::MainProgram->_new(),
			ETL::Pequel3::Generator::SubProgram->_new(),
			ETL::Pequel3::Generator::TableLoader->_new(),
		);
		return $self;
	}
}
# ----------------------------------------------------------------------------------------------------
# SEGMENT TYPE
# ----------------------------------------------------------------------------------------------------
{
	package ETL::Pequel3::Generator::Segment::Abstract; 
	use base qw(Class::STL::Element);
	use Class::STL::ClassMembers 
		qw( err properties catalogue package_name user_prog main segment_name segments ),
		Class::STL::ClassMembers::DataMember->new(name => 'show_info', default => 1);
	use Class::STL::ClassMembers::Constructor;
	sub new_extra
	{
		my $self = shift;
		use ETL::Pequel3::Error;
		$self->err(ETL::Pequel3::Error->new()); # Singleton
		use ETL::Pequel3::Type::Properties;
		$self->properties(ETL::Pequel3::Type::Properties->new()); # Singleton
		use ETL::Pequel3::Catalogue;
		$self->catalogue(ETL::Pequel3::Catalogue->new());

		$self->err()->user_error(10502, "Class @{[ ref($self) ]}::user_prog is undefined!")
			unless (defined($self->user_prog()));
		use stl qw(list);
		$self->segments(list(element_type => 'ETL::Pequel3::Generator::Segment::Abstract'));
		$self->package_name("Pequel::@{[ do { my $n=$self->main()->pequel_name();$n=~s/\W+/_/g;$n } ]}")
			unless (defined($self->package_name()) || !defined($self->main()));
	}
	sub program_info
	{
		my $self = shift;
		my $extra = shift;
		return unless ($self->show_info());
		$self->user_prog()->comment("");
		$self->user_prog()->comment(" ++++ @{[ join(' ', map(ucfirst($_), split(/_/, $self->segment_name()))) ]}@{[ defined($extra) ? qq/ ($extra)/ : '' ]} Segment ++++");
		$self->user_prog()->comment("");
	}
	sub prepare_start
	{
		my $self = shift;
		$self->err()->diag(20, "...@{[ $_->segment_name() ]}...");
		map($_->prepare_start(), $self->segments()->to_array());
	}
	sub prepare_finish
	{
		my $self = shift;
		map($_->prepare_finish(), CORE::reverse($self->segments()->to_array()));
	}
	sub prepare
	{
		my $self = shift;
		$self->prepare_start();
		$self->prepare_finish();
	}
}
# ----------------------------------------------------------------------------------------------------
{
	package ETL::Pequel3::Generator::Segment::SubPrograms; 
	use base qw(ETL::Pequel3::Generator::Segment::Abstract);
	use Class::STL::ClassMembers
		Class::STL::ClassMembers::DataMember->new(name => 'segment_name', default => 'sub_programs');
	use Class::STL::ClassMembers::Constructor; 
	sub prepare
	{
		my $self = shift;
		$self->program_info();
#?		foreach ($self->main()->all_pequels()->to_array()) {
		foreach (grep($_->duplicate() == 0, $self->main()->user_pequels()->to_array())) {
			my $sub = ETL::Pequel3::Generator::SubProgram->new(main => $_);
			$sub->build();
			$self->user_prog()->add($sub->user_prog());
		}
	}
}
# ----------------------------------------------------------------------------------------------------
{
	package ETL::Pequel3::Generator::Segment::MainPackage; 
	use base qw(ETL::Pequel3::Generator::Segment::Abstract);
	use Class::STL::ClassMembers
		Class::STL::ClassMembers::DataMember->new(name => 'segment_name', default => 'main_package');
	use Class::STL::ClassMembers::Constructor; 
	sub new_extra
	{
		my $self = shift;
		$self->segments()->push_back(
			$self->catalogue()->code_segments()->package()->new(@_),
			$self->catalogue()->code_segments()->header_info()->new(@_),
			$self->catalogue()->code_segments()->sub_execute_body()->new(@_),
		);
	}
}
# ----------------------------------------------------------------------------------------------------
{	
	package ETL::Pequel3::Generator::Segment::SubExecuteBody; 
	use base qw(ETL::Pequel3::Generator::Segment::Abstract);
	use Class::STL::ClassMembers
		Class::STL::ClassMembers::DataMember->new(name => 'segment_name', default => 'sub_execute_body');
	use Class::STL::ClassMembers::Constructor;
	sub new_extra
	{
		my $self = shift;
		$self->segments()->push_back(
			$self->catalogue()->code_segments()->sub_execute_def()->new(@_),
			$self->catalogue()->code_segments()->declaration()->new(@_),
			$self->catalogue()->code_segments()->init_local()->new(@_),
			$self->catalogue()->code_segments()->open_local()->new(@_),
			$self->catalogue()->code_segments()->finish()->new(@_),
			$self->catalogue()->code_segments()->main()->new(@_),
		);
	}
}	
# ----------------------------------------------------------------------------------------------------
{	
	package ETL::Pequel3::Generator::Segment::SubExecuteDef; 
	use base qw(ETL::Pequel3::Generator::Segment::Abstract);
	use Class::STL::ClassMembers
		Class::STL::ClassMembers::DataMember->new(name => 'segment_name', default => 'sub_execute_def');
	use Class::STL::ClassMembers::Constructor;
	sub prepare_start
	{
		my $self = shift;
		$self->user_prog()->code("sub execute");
		$self->user_prog()->open_block();
	}
	sub prepare_finish
	{
		my $self = shift;
		$self->user_prog()->close_block();
	}
}	
# ----------------------------------------------------------------------------------------------------
{
	package ETL::Pequel3::Generator::Segment::Startup; 
	use base qw(ETL::Pequel3::Generator::Segment::Abstract);
	use Class::STL::ClassMembers
		Class::STL::ClassMembers::DataMember->new(name => 'segment_name', default => 'startup');
	use Class::STL::ClassMembers::Constructor; 
	sub prepare_start
	{
		my $self = shift;
		$self->user_prog()->indent_off();
		$self->user_prog()->comment("!$^X");
		$self->user_prog()->indent_on();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -