our
$VERSION
=
"0.47"
;
$SIG
{__DIE__} = \
&Carp::confess
;
my
@PERL5LIB
= (
$ENV
{PERL5LIB} ?
split
(
':'
,
$ENV
{PERL5LIB}) : ());
for
my
$dir
(
@INC
,
@PERL5LIB
) {
next
unless
-d
$dir
;
$dir
= Cwd::abs_path(
$dir
) ||
$dir
;
}
$ENV
{PERL5LIB} =
join
(
':'
,
@PERL5LIB
);
for
my
$module
(
keys
%INC
) {
$INC
{
$module
} = Cwd::abs_path(
$INC
{
$module
});
}
for
my
$e
(
keys
%ENV
) {
next
unless
substr
(
$e
,0,3) eq
'UR_'
;
eval
"use UR::Env::$e"
;
if
($@) {
my
$path
= __FILE__;
$path
=~ s/.pm$//;
my
@files
=
glob
(
"\Q${path}\E/Env/*"
);
my
@vars
=
map
{ /UR\/Env\/(.*).pm/; $1 }
@files
;
print
STDERR
"Environment variable $e set to $ENV{$e} but there were errors using UR::Env::$e:\n"
.
"Available variables:\n\t"
.
join
(
"\n\t"
,
@vars
)
.
"\n"
;
exit
1;
}
}
END {
if
(
$ENV
{UR_USED_LIBS}) {
print
STDERR
"Used library include paths (\@INC):\n"
;
for
my
$lib
(
@INC
) {
print
STDERR
"$lib\n"
;
}
print
STDERR
"\n"
;
}
if
(
$ENV
{UR_USED_MODS}) {
print
STDERR
"Used modules and paths (\%INC):\n"
;
for
my
$mod
(
sort
keys
%INC
) {
if
(
$ENV
{UR_USED_MODS} > 1) {
print
STDERR
"$mod => $INC{$mod}\n"
;
}
else
{
print
STDERR
"$mod\n"
;
}
}
print
STDERR
"\n"
;
}
if
(
$ENV
{UR_DBI_SUMMARIZE_SQL}) {
UR::DBI::print_sql_summary();
}
}
BEGIN {
my
$v
=
$Class::Autouse::VERSION
;
unless
((
$v
=~ /^\d+\.?\d*$/ &&
$v
>= 2.0)
or
$v
eq
'1.99_02'
or
$v
eq
'1.99_04'
) {
die
"UR requires Class::Autouse 2.0 or greater (or 1.99_02 or 1.99_04)!!"
;
}
};
UR::Object::Type->define(
class_name
=>
'UR::Object'
,
is
=> [],
is_abstract
=> 1,
composite_id_separator
=>
"\t"
,
id_by
=> [
id
=> {
is
=>
'Scalar'
,
doc
=>
'unique identifier'
}
],
id_generator
=>
'-urinternal'
,
);
UR::Object::Type->define(
class_name
=>
"UR::Object::Index"
,
id_by
=> [
'indexed_class_name'
,
'indexed_property_string'
],
has
=> [
'indexed_class_name'
,
'indexed_property_string'
],
is_transactional
=> 0,
);
UR::Object::Type->define(
class_name
=>
'UR::Object::Ghost'
,
is_abstract
=> 1,
);
UR::Object::Type->define(
class_name
=>
'UR::Entity'
,
extends
=> [
'UR::Object'
],
is_abstract
=> 1,
);
UR::Object::Type->define(
class_name
=>
'UR::Entity::Ghost'
,
extends
=> [
'UR::Object::Ghost'
],
is_abstract
=> 1,
);
UR::Object::Type->define(
class_name
=>
'UR::Object::Type'
,
doc
=>
'class/type meta-objects for UR'
,
id_by
=>
'class_name'
,
sub_classification_method_name
=>
'_resolve_meta_class_name'
,
is_abstract
=> 1,
has
=> [
class_name
=> {
is
=>
'Text'
,
len
=> 256,
is_optional
=> 1,
doc
=>
'the name for the class described'
},
properties
=> {
is_many
=> 1,
calculate
=>
'shift->_properties(@_);'
,
doc
=>
'property meta-objects for the class'
},
id_properties
=> {
is_many
=> 1,
calculate
=>
q( grep { defined $_->is_id } shift->_properties(@_)
),
doc
=>
'meta-objects for the ID properties of the class'
},
doc
=> {
is
=>
'Text'
,
len
=> 1024,
is_optional
=> 1,
doc
=>
'a one-line description of the class/type'
},
is_abstract
=> {
is
=>
'Boolean'
,
default_value
=> 0,
doc
=>
'abstract classes must be subclassified into a concreate class at create/load time'
},
is_final
=> {
is
=>
'Boolean'
,
default_value
=> 0,
doc
=>
'further subclassification is prohibited on final classes'
},
is_transactional
=> {
is
=>
'Boolean'
,
default_value
=> 1,
is_optional
=> 1,
doc
=>
'non-transactional objects are left out of in-memory transactions'
},
is_singleton
=> {
is
=>
'Boolean'
,
default_value
=> 0,
doc
=>
'singleton classes have only one instance, or have each instance fall into a distinct subclass'
},
namespace
=> {
is
=>
'Text'
,
len
=> 256,
is_optional
=> 1,
doc
=>
'the first "word" in the class name, which points to a UR::Namespace'
},
schema_name
=> {
is
=>
'Text'
,
len
=> 256,
is_optional
=> 1,
doc
=>
'an arbitrary grouping for classes for which instances share a common storage system'
},
data_source_id
=> {
is
=>
'Text'
,
len
=> 256,
is_optional
=> 1,
doc
=>
'for classes which persist beyond their current process, the identifier for their storage manager'
},
generated
=> {
is
=>
'Boolean'
,
is_transient
=> 1,
default_value
=> 0,
doc
=>
'an internal flag set when the class meta has fabricated accessors and methods in the class namespace'
},
meta_class_name
=> {
is
=>
'Text'
,
doc
=>
'even meta-classess have a meta-class'
},
composite_id_separator
=> {
is
=>
'Text'
,
len
=> 2 ,
default_value
=>
"\t"
,
is_optional
=> 1,
doc
=>
'for classes whose objects have a multi-value "id", this overrides using a "\t" to compose/decompose'
},
valid_signals
=> {
is
=>
'ARRAY'
,
is_optional
=> 1,
doc
=>
'List of non-standard signal names observers can bind to '
},
table_name
=> {
is
=>
'Text'
,
len
=>
undef
,
is_optional
=> 1,
doc
=>
'for classes with a data source, this specifies the table or equivalent data structure which holds instances'
},
select_hint
=> {
is
=>
'Text'
,
len
=> 1024 ,
is_optional
=> 1,
doc
=>
'used to optimize access to underlying storage (database specific)'
},
join_hint
=> {
is
=>
'Text'
,
len
=> 1024 ,
is_optional
=> 1,
doc
=>
'used to optimize access to underlying storage when this class is part of a join (database specific)'
},
id_generator
=> {
is
=>
'Text'
,
len
=> 256,
is_optional
=> 1,
doc
=>
'override the default choice for generating new object IDs'
},
subclassify_by
=> {
is
=>
'Text'
,
len
=> 256,
is_optional
=> 1,
doc
=>
'when set, the method specified will return the name of a specific subclass into which the object should go'
},
subclass_description_preprocessor
=> {
is
=>
'MethodName'
,
len
=> 255,
is_optional
=> 1,
doc
=>
'a method which should pre-process the class description of sub-classes before construction'
},
sub_classification_method_name
=> {
is
=>
'Text'
,
len
=> 256,
is_optional
=> 1,
doc
=>
'like subclassify_by, but examines whole objects not a single property'
},
use_parallel_versions
=> {
is
=>
'Boolean'
,
is_optional
=> 1,
default_value
=> 0,
doc
=>
'inheriting from the is class will redirect to a ::V? module implemeting a specific version'
},
type_name
=> {
is
=>
'Text'
,
len
=> 256,
is_deprecated
=> 1,
is_optional
=> 1 },
er_role
=> {
is
=>
'Text'
,
len
=> 256,
is_optional
=> 1,
default_value
=>
'entity'
},
source
=> {
is
=>
'Text'
,
len
=> 256 ,
default_value
=>
'data dictionary'
,
is_optional
=> 1 },
sub_classification_meta_class_name
=> {
is
=>
'Text'
,
len
=> 1024 ,
is_optional
=> 1,
doc
=>
'obsolete'
},
first_sub_classification_method_name
=> {
is
=>
'Text'
,
len
=> 256,
is_optional
=> 1,
doc
=>
'cached value to handle a complex inheritance hierarchy with storage at some levels but not others'
},
namespace_meta
=> {
is
=>
'UR::Namespace'
,
id_by
=>
'namespace'
},
is
=> {
is
=>
'ARRAY'
,
is_mutable
=> 0,
doc
=>
'List of the parent class names'
},
roles
=> {
is
=>
'ARRAY'
,
is_mutable
=> 0,
is_optional
=> 1,
doc
=>
'List of the roles consumed by this class'
},
parent_class_metas
=> {
is
=>
'UR::Object::Type'
,
id_by
=>
'is'
,
doc
=>
'The list of UR::Object::Type objects for the classes that are direct parents of this class'
},
parent_class_names
=> {
via
=>
'parent_class_metas'
,
to
=>
'class_name'
,
is_many
=> 1 },
parent_meta_class_names
=> {
via
=>
'parent_class_metas'
,
to
=>
'meta_class_name'
,
is_many
=> 1 },
ancestry_meta_class_names
=> {
via
=>
'ancestry_class_metas'
,
to
=>
'meta_class_name'
,
is_many
=> 1 },
ancestry_class_metas
=> {
is
=>
'UR::Object::Type'
,
id_by
=>
'is'
,
where
=> [
-recurse
=> [
class_name
=>
'is'
]],
doc
=>
'Climb the ancestry tree and return the class objects for all of them'
},
ancestry_class_names
=> {
via
=>
'ancestry_class_metas'
,
to
=>
'class_name'
,
is_many
=> 1 },
all_class_metas
=> {
is
=>
'UR::Object::Type'
,
calculate
=>
'return ($self, $self->ancestry_class_metas)'
},
direct_property_metas
=> {
is
=>
'UR::Object::Property'
,
reverse_as
=>
'class_meta'
,
is_many
=> 1 },
direct_property_names
=> {
via
=>
'direct_property_metas'
,
to
=>
'property_name'
,
is_many
=> 1 },
direct_id_property_metas
=> {
is
=>
'UR::Object::Property'
,
reverse_as
=>
'class_meta'
,
where
=> [
'is_id true'
=> 1,
-order_by
=>
'is_id'
],
is_many
=> 1 },
direct_id_property_names
=> {
via
=>
'direct_id_property_metas'
,
to
=>
'property_name'
,
is_many
=> 1 },
ancestry_property_metas
=> {
via
=>
'ancestry_class_metas'
,
to
=>
'direct_property_metas'
,
is_many
=> 1 },
ancestry_property_names
=> {
via
=>
'ancestry_class_metas'
,
to
=>
'direct_property_names'
,
is_many
=> 1 },
ancestry_id_property_metas
=> {
via
=>
'ancestry_class_metas'
,
to
=>
'direct_id_property_metas'
,
is_many
=> 1 },
ancestry_id_property_names
=> {
via
=>
'ancestry_id_property_metas'
,
to
=>
'property_name'
,
is_many
=> 1 },
all_property_metas
=> {
via
=>
'all_class_metas'
,
to
=>
'direct_property_metas'
,
is_many
=> 1 },
all_property_names
=> {
via
=>
'all_property_metas'
,
to
=>
'property_name'
,
is_many
=> 1 },
all_id_property_metas
=> {
via
=>
'all_class_metas'
,
to
=>
'direct_id_property_metas'
,
is_many
=> 1 },
all_id_property_names
=> {
via
=>
'all_id_property_metas'
,
to
=>
'property_name'
,
is_many
=> 1 },
direct_id_by_property_metas
=> {
via
=>
'direct_property_metas'
,
to
=>
'__self__'
,
where
=> [
'id_by true'
=> 1],
is_many
=> 1,
doc
=>
"Properties with 'id_by' metadata, ie. direct object accessor properties"
} ,
all_id_by_property_metas
=> {
via
=>
'all_class_metas'
,
to
=>
'direct_id_by_property_metas'
,
is_many
=> 1},
direct_reverse_as_property_metas
=> {
via
=>
'direct_property_metas'
,
to
=>
'__self__'
,
where
=> [
'reverse_as true'
=> 1],
is_many
=> 1,
doc
=>
"Properties with 'reverse_as' metadata, ie. indirect object accessor properties"
},
all_reverse_as_property_metas
=> {
via
=>
'all_class_metas'
,
to
=>
'direct_reverse_as_property_metas'
,
is_many
=> 1},
direct_column_names
=> {
via
=>
'direct_property_metas'
,
to
=>
'column_name'
,
is_many
=> 1,
where
=> [
column_name
=> {
operator
=>
'true'
}] },
direct_id_column_names
=> {
via
=>
'direct_id_property_metas'
,
to
=>
'column_name'
,
is_many
=> 1,
where
=> [
column_name
=> {
operator
=>
'true'
}] },
ancestry_column_names
=> {
via
=>
'ancestry_class_metas'
,
to
=>
'direct_column_names'
,
is_many
=> 1 },
ancestry_id_column_names
=> {
via
=>
'ancestry_class_metas'
,
to
=>
'direct_id_column_names'
,
is_many
=> 1 },
direct_columnless_property_metas
=> {
is
=>
'UR::Object::Property'
,
reverse_as
=>
'class_meta'
,
where
=> [
column_name
=>
undef
],
is_many
=> 1 },
direct_columnless_property_names
=> {
via
=>
'direct_columnless_property_metas'
,
to
=>
'property_name'
,
is_many
=> 1 },
ancestry_columnless_property_metas
=> {
via
=>
'ancestry_class_metas'
,
to
=>
'direct_columnless_property_metas'
,
is_many
=> 1 },
ancestry_columnless_property_names
=> {
via
=>
'ancestry_columnless_property_metas'
,
to
=>
'property_name'
,
is_many
=> 1 },
ancestry_table_names
=> {
via
=>
'ancestry_class_metas'
,
to
=>
'table_name'
,
is_many
=> 1 },
all_table_names
=> {
via
=>
'all_class_metas'
,
to
=>
'table_name'
,
is_many
=> 1 },
all_column_names
=> {
via
=>
'all_class_metas'
,
to
=>
'direct_column_names'
,
is_many
=> 1 },
all_id_column_names
=> {
via
=>
'all_class_metas'
,
to
=>
'direct_id_column_names'
,
is_many
=> 1 },
all_columnless_property_metas
=> {
via
=>
'all_class_metas'
,
to
=>
'direct_columnless_property_metas'
,
is_many
=> 1 },
all_columnless_property_names
=> {
via
=>
'all_class_metas'
,
to
=>
'direct_columnless_property_names'
,
is_many
=> 1 },
],
);
UR::Object::Type->define(
class_name
=>
'UR::Object::Property'
,
id_properties
=> [
class_name
=> {
is
=>
'Text'
,
len
=> 256 },
property_name
=> {
is
=>
'Text'
,
len
=> 256 },
],
has_optional
=> [
property_type
=> {
is
=>
'Text'
,
len
=> 256 ,
is_optional
=> 1},
column_name
=> {
is
=>
'Text'
,
len
=> 256,
is_optional
=> 1 },
data_length
=> {
is
=>
'Text'
,
len
=> 32,
is_optional
=> 1 },
data_type
=> {
is
=>
'Text'
,
len
=> 256,
is_optional
=> 1 },
calculated_default
=> {
is_optional
=> 1 },
default_value
=> {
is_optional
=> 1 },
valid_values
=> {
is
=>
'ARRAY'
,
is_optional
=> 1, },
example_values
=> {
is
=>
'ARRAY'
,
is_optional
=> 1,
doc
=>
'example valid values; used to generate help text for Commands'
},
doc
=> {
is
=>
'Text'
,
len
=> 1000,
is_optional
=> 1 },
is_id
=> {
is
=>
'Integer'
,
default_value
=>
undef
,
doc
=>
'denotes this is an ID property of the class, and ranks them'
},
is_optional
=> {
is
=>
'Boolean'
,
default_value
=> 0},
is_transient
=> {
is
=>
'Boolean'
,
default_value
=> 0},
is_constant
=> {
is
=>
'Boolean'
,
default_value
=> 0},
is_mutable
=> {
is
=>
'Boolean'
,
default_value
=> 1},
is_volatile
=> {
is
=>
'Boolean'
,
default_value
=> 0},
is_classwide
=> {
is
=>
'Boolean'
,
default_value
=> 0},
is_delegated
=> {
is
=>
'Boolean'
,
default_value
=> 0},
is_calculated
=> {
is
=>
'Boolean'
,
default_value
=> 0},
is_transactional
=> {
is
=>
'Boolean'
,
default_value
=> 1},
is_abstract
=> {
is
=>
'Boolean'
,
default_value
=> 0},
is_concrete
=> {
is
=>
'Boolean'
,
default_value
=> 1},
is_final
=> {
is
=>
'Boolean'
,
default_value
=> 0},
is_many
=> {
is
=>
'Boolean'
,
default_value
=> 0},
is_aggregate
=> {
is
=>
'Boolean'
,
default_value
=> 0},
is_deprecated
=> {
is
=>
'Boolean'
,
default_value
=> 0},
is_numeric
=> {
calculate_from
=> [
'data_type'
], },
id_by
=> {
is
=>
'ARRAY'
,
is_optional
=> 1},
id_class_by
=> {
is
=>
'Text'
,
is_optional
=> 1},
is_undocumented
=> {
is
=>
'Boolean'
,
is_optional
=> 1,
doc
=>
'do not show in documentation to users'
},
doc_position
=> {
is
=>
'Number'
,
is_optional
=> 1,
doc
=>
'override the sort position within documentation'
},
access_as
=> {
is
=>
'Text'
,
is_optional
=> 1,
doc
=>
'when id_class_by is set, and this is set to "auto", primitives will return as their ID instead of boxed'
},
order_by
=> {
is
=>
'ARRAY'
,
is_optional
=> 1},
specify_by
=> {
is
=>
'Text'
,
is_optional
=> 1},
reverse_as
=> {
is
=>
'ARRAY'
,
is_optional
=> 1 },
implied_by
=> {
is
=>
'Text'
,
is_optional
=> 1},
via
=> {
is
=>
'Text'
,
is_optional
=> 1 },
to
=> {
is
=>
'Text'
,
is_optional
=> 1},
where
=> {
is
=>
'ARRAY'
,
is_optional
=> 1},
calculate
=> {
is
=>
'Text'
,
is_optional
=> 1},
calculate_from
=> {
is
=>
'ARRAY'
,
is_optional
=> 1},
calculate_perl
=> {
is
=>
'Perl'
,
is_optional
=> 1},
calculate_sql
=> {
is
=>
'SQL'
,
is_optional
=> 1},
calculate_js
=> {
is
=>
'JavaScript'
,
is_optional
=> 1},
constraint_name
=> {
is
=>
'Text'
,
is_optional
=> 1},
is_legacy_eav
=> {
is
=>
'Boolean'
,
is_optional
=> 1},
is_dimension
=> {
is
=>
'Boolean'
,
is_optional
=> 1},
is_specified_in_module_header
=> {
is
=>
'Boolean'
,
default_value
=> 0 },
position_in_module_header
=> {
is
=>
'Integer'
,
is_optional
=> 1,
doc
=>
"Line in the class definition source's section this property appears"
},
singular_name
=> {
is
=>
'Text'
},
plural_name
=> {
is
=>
'Text'
},
class_meta
=> {
is
=>
'UR::Object::Type'
,
id_by
=>
'class_name'
},
r_class_meta
=> {
is
=>
'UR::Object::Type'
,
id_by
=>
'data_type'
},
],
unique_constraints
=> [
{
properties
=> [
qw/property_name class_name/
],
sql
=>
'SUPER_FAKE_O4'
},
],
);
UR::Object::Type->define(
class_name
=>
'UR::Object::Property::Calculated::From'
,
id_properties
=> [
qw/class_name calculated_property_name source_property_name/
],
);
UR::Object::Type->define(
class_name
=>
'UR'
,
extends
=> [
'UR::Namespace'
],
);
UR::Object::Type->initialize_bootstrap_classes;
$UR::initialized
= 1;
do
{
UR::Context->_initialize_for_current_process();
};
sub
main::ur_core {
print
STDERR
"Dumping rules and templates to ./ur_core.stor...\n"
;
my
$dump
;
unless
(
open
(
$dump
,
">ur_core.stor"
)) {
print
STDERR
"Can't open ur_core.stor for writing: $!"
;
exit
;
}
store_fd([
$UR::Object::rule_templates
,
$UR::Object::rules
,
],
$dump
);
close
$dump
;
exit
();
}
1;
Hide Show 336 lines of Pod