/[cvs]/nfo/perl/libs/Data/Storage/Schema/Abstract.pm
ViewVC logotype

Contents of /nfo/perl/libs/Data/Storage/Schema/Abstract.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (show annotations)
Mon Dec 16 06:45:07 2002 UTC (21 years, 6 months ago) by joko
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +70 -39 lines
+ injecting property 'guid' into each conrete class when initializing the schema

1 ## ------------------------------------------------------------------------
2 ## $Id: Abstract.pm,v 1.6 2002/11/17 07:21:47 jonen Exp $
3 ## ------------------------------------------------------------------------
4 ## $Log: Abstract.pm,v $
5 ## Revision 1.6 2002/11/17 07:21:47 jonen
6 ## + using Class::Tangram::import_schema() again for proper usage of its helper functions
7 ##
8 ## Revision 1.5 2002/11/17 07:12:06 joko
9 ## + extended ::getProperties with argument "want_transactions"
10 ##
11 ## Revision 1.4 2002/11/15 13:21:39 joko
12 ## + added capability to propagate global schema options from schema module to tangram schema
13 ##
14 ## Revision 1.3 2002/11/09 01:27:23 joko
15 ## + dependency of Class::Tangram now is 1.13 at minimum
16 ##
17 ## Revision 1.2 2002/10/25 11:45:10 joko
18 ## + enhanced robustness
19 ## + more logging for debug-levels
20 ##
21 ## Revision 1.1 2002/10/17 00:07:14 joko
22 ## + new
23 ## ------------------------------------------------------------------------
24
25
26 package Data::Storage::Schema::Abstract;
27
28 use strict;
29 use warnings;
30
31 use Tangram;
32 use Class::Tangram;
33
34 use Tangram::RawDate;
35 use Tangram::RawTime;
36 use Tangram::RawDateTime;
37
38 use Tangram::FlatArray;
39 use Tangram::FlatHash;
40 use Tangram::PerlDump;
41
42
43 use Data::Dumper;
44
45 # get logger instance
46 my $logger = Log::Dispatch::Config->instance;
47
48
49
50 # ======== object constructor - %args to $self ========
51 sub new {
52 my $invocant = shift;
53 my $class = ref($invocant) || $invocant;
54 my @args = ();
55 @_ && (@args = @_);
56
57 $logger->debug( __PACKAGE__ . "->new" );
58
59 #my $self = { @_ };
60
61 # merge all entries from all hashes in args-array to single array (key, val, key, val)
62 my @args_all = ();
63 map { push(@args_all, %{$_}); } @args;
64 # make hash from array
65 my %args = @args_all;
66
67 #$logger->debug( __PACKAGE__ . "->new( @args_all )" );
68
69 my $self = { %args };
70 bless $self, $class;
71
72 #use Data::Dumper; print Dumper($self);
73
74 # remember as which Class we are instantiated
75 $self->{invocant} = $invocant;
76
77 $self->_checkClassTangram();
78 $self->_init();
79
80 return $self;
81 }
82
83 sub _checkClassTangram {
84 my $self = shift;
85 # check version of "Class::Tangram"
86 my $ctversion = $Class::Tangram::VERSION;
87 #print "ctversion: ", $ctversion, "\n";
88 #if ($ctversion ne 1.04) {
89 if ($ctversion lt 1.13) {
90 print "Version of \"Class::Tangram\": ", $ctversion, "\n";
91 print "minimum required version : ", "1.13", "\n";
92 #print "quitting!!! (please install older version (1.04) of \"Class::Tangram\"", "\n";
93 exit;
94 }
95 }
96
97 sub _parsePackageNamesFromFile {
98 my $self = shift;
99 my $filename = shift;
100 my $exclude_pattern = shift;
101 $logger->debug( __PACKAGE__ . "->_parsePackageFile( ... )" );
102 if (!$filename) {
103 $logger->error( __PACKAGE__ . "->_parsePackageFile: you must specify a filename" );
104 return;
105 }
106 if (! -e $filename) {
107 $logger->error( __PACKAGE__ . "->_parsePackageFile: could not find $filename" );
108 }
109 my @packages = ();
110 open(FH, '<' . $filename);
111 while (<FH>) {
112 chomp();
113 my $good = 1;
114 $exclude_pattern && ($good = !m/$exclude_pattern/);
115 push @packages, $1 if m/^package (.+?);/ && $good;
116 }
117 close(FH);
118 return \@packages;
119 }
120
121 sub _doinit {
122 my $self = shift;
123
124 $logger->debug( __PACKAGE__ . "->_doinit()" );
125
126 # WHAT?
127 # imports classes to Tangram-Schema in this style, but in an abstracted way:
128 # Class::Tangram::import_schema("SystemEvent");
129 # TODO:
130 # move this code to Data::Storage::Schema::Tangram
131
132 # TODO:
133 # two cases:
134 # 1. use a given list of strings as to-be-used-object-names
135 # 2. parse the content of the given package and use all declared Perl Packages as objects
136
137 my $classlist = $self->{EXPORT_OBJECTS};
138
139 # parse complete package to build list of classes
140 if ($#{$classlist} == -1) {
141 $logger->debug( "_doinit() Initializing all Classes from " . $self->{invocant} );
142 if (!$self->{invocant}->can('getFilename')) {
143 $logger->error( __PACKAGE__ . "->_doinit: Package $self->{invocant} doesn't contain method 'getFilename'" );
144 return;
145 }
146 my $perl_packagefile = eval('return ' . $self->{invocant} . '::getFilename();');
147 my $packages = $self->_parsePackageNamesFromFile($perl_packagefile, $self->{invocant});
148 # TODO:
149 # cache list so this routine isn't called on every startup/request
150 $classlist = $packages;
151 }
152
153 my $schema_properties = {};
154 if ($self->{invocant}->can('getProperties')) {
155 # TODO: rework this! call by ref and/or do oo
156 #$schema_properties = eval('return ' . $self->{invocant} . '::getProperties();');
157 $schema_properties = eval('return ' . $self->{invocant} . '::getProperties($self->{want_transactions});');
158 }
159
160 # build temporary index to look up class by classname
161 my $classindex = {};
162
163 # build argument to be passed to "Tangram::Schema->new(...)"
164 my @classes;
165 map {
166 $logger->debug( __PACKAGE__ . "->_doinit: Initializing Class $_" );
167 Class::Tangram::import_schema($_);
168 # classname
169 push @classes, $_;
170 # schema
171 my $schema;
172 my $evalstr = '$schema = $' . $_ . '::schema;';
173 my $res = eval($evalstr);
174 push @classes, $schema;
175 $classindex->{$_} = $schema;
176 } @{$classlist};
177
178 # build up the schema as a hash
179 my $schema = {
180 classes => \@classes,
181 };
182
183 # merge schema properties
184 foreach (keys %$schema_properties) {
185 $schema->{$_} = $schema_properties->{$_};
186 }
187
188 #print Dumper($schema);
189
190 # patch guid into each concrete (non-abstract) object
191 # TODO: refactor this code into function: _injectProperty('guid')
192 foreach (@{$schema->{classes}}) {
193 my $ref = ref $_;
194 next if !$ref || $ref ne 'HASH';
195 next if $_->{abstract};
196
197 #print Dumper($_);
198
199 if (!$_->{fields}->{string}) {
200 $_->{fields}->{string}->{guid} = undef;
201
202 } elsif (ref $_->{fields}->{string} eq 'ARRAY') {
203 push @{$_->{fields}->{string}}, 'guid';
204
205 } elsif (ref $_->{fields}->{string} eq 'HASH') {
206 $_->{fields}->{string}->{guid} = undef;
207
208 }
209 }
210
211 # create a new Tangram schema object
212 # a) these classes must occour in the same order used at a previous setup or
213 # b) better use class ids!
214 $self->{schema} = Tangram::Schema->new($schema);
215 return 1;
216
217 =pod
218 # ======================================
219 # schema template
220 $self->{schema} = Tangram::Schema->new({
221
222 classes => [
223 # misc
224 'Person' => $Person::schema,
225 ],
226
227 make_object => sub { ... },
228 set_id => sub { ... }
229 get_id => sub { ... }
230 normalize => sub { ... },
231
232 control => '...'
233
234 sql => { ... },
235
236 });
237 # ======================================
238 =cut
239
240 }
241
242 sub _init {
243 my $self = shift;
244 if (!$self->{schema}) {
245 $self->_doinit();
246 }
247 }
248
249 # return schema
250 sub getSchema {
251 my $self = shift;
252 if (!$self->{schema}) {
253 #print "schema is not yet initialized!", "\n";
254 #exit;
255 $logger->error( __PACKAGE__ . "->getSchema: Schema is not yet initialized!" );
256 return;
257 }
258 return $self->{schema};
259 }
260
261
262 1;

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed