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

Diff of /nfo/perl/libs/Data/Storage.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by joko, Tue Oct 29 19:24:18 2002 UTC revision 1.8 by joko, Fri Nov 29 04:48:23 2002 UTC
# Line 4  Line 4 
4  #  #
5  # See COPYRIGHT section in pod text below for usage and distribution rights.  # See COPYRIGHT section in pod text below for usage and distribution rights.
6  #  #
7  #################################  ############################################
8  #  #
9  #  $Log$  #  $Log$
10    #  Revision 1.8  2002/11/29 04:48:23  joko
11    #  + updated pod
12    #
13    #  Revision 1.7  2002/11/17 06:07:18  joko
14    #  + creating the handler is easier than proposed first - for now :-)
15    #  + sub testAvailability
16    #
17    #  Revision 1.6  2002/11/09 01:04:58  joko
18    #  + updated pod
19    #
20  #  Revision 1.5  2002/10/29 19:24:18  joko  #  Revision 1.5  2002/10/29 19:24:18  joko
21  #  - reduced logging  #  - reduced logging
22  #  + added some pod  #  + added some pod
# Line 27  Line 37 
37  #  Revision 1.1  2002/10/10 03:43:12  cvsjoko  #  Revision 1.1  2002/10/10 03:43:12  cvsjoko
38  #  + new  #  + new
39  #  #
40  #################################  ############################################
41    
 # aim_V1: should encapsulate Tangram, DBI, DBD::CSV and LWP:: to access them in an unordinary way ;)  
 # aim_V2: introduce a generic layered structure, refactor *SUBLAYER*-stuff, make (e.g.) this possible:  
 #               - Perl Data::Storage[DBD::CSV]  ->  Perl LWP::  ->  Internet HTTP/FTP/*  ->  Host Daemon  ->  csv-file  
42    
43  BEGIN {  BEGIN {
44  $Data::Storage::VERSION = 0.01;    $Data::Storage::VERSION = 0.02;
45  }  }
46    
47    
# Line 42  $Data::Storage::VERSION = 0.01; Line 49  $Data::Storage::VERSION = 0.01;
49    
50  Data::Storage - Interface for accessing various Storage implementations for Perl in an independent way  Data::Storage - Interface for accessing various Storage implementations for Perl in an independent way
51    
52    
53    =head1 AIMS
54    
55      - should encapsulate Tangram, DBI, DBD::CSV and LWP:: to access them in an unordinary (more convenient) way ;)
56      - introduce a generic layered structure, refactor *SUBLAYER*-stuff, make (e.g.) this possible:
57        Perl Data::Storage[DBD::CSV]  ->  Perl LWP::  ->  Internet HTTP/FTP/*  ->  Host Daemon  ->  csv-file
58      - provide generic synchronization mechanisms across arbitrary/multiple storages based on ident/checksum
59        maybe it's possible to have schema-, structural- and semantical modifications synchronized???
60    
61    
62  =head1 SYNOPSIS  =head1 SYNOPSIS
63    
64    ... the basic way:  =head2 BASIC ACCESS
65    
66    =head2 ADVANCED ACCESS
67    
68    ... via inheritance:    ... via inheritance:
69        
# Line 63  Data::Storage - Interface for accessing Line 81  Data::Storage - Interface for accessing
81      $self->{storage}->insert($proxyObj);      $self->{storage}->insert($proxyObj);
82    
83    
84    =head2 SYNCHRONIZATION
85    
86      my $nodemapping = {
87        'LangText' => 'langtexts.csv',
88        'Currency' => 'currencies.csv',
89        'Country'  => 'countries.csv',
90      };
91    
92      my $propmapping = {
93        'LangText' => [
94          [ 'source:lcountrykey'  =>  'target:country' ],
95          [ 'source:lkey'         =>  'target:key' ],
96          [ 'source:lvalue'       =>  'target:text' ],
97        ],
98        'Currency' => [
99          [ 'source:ckey'         =>  'target:key' ],
100          [ 'source:cname'        =>  'target:text' ],
101        ],
102        'Country' => [
103          [ 'source:ckey'         =>  'target:key' ],
104          [ 'source:cname'        =>  'target:text' ],
105        ],
106      };
107    
108      sub syncResource {
109    
110        my $self = shift;
111        my $node_source = shift;
112        my $mode = shift;
113        my $opts = shift;
114        
115        $mode ||= '';
116        $opts->{erase} ||= 0;
117        
118        $logger->info( __PACKAGE__ . "->syncResource( node_source $node_source mode $mode erase $opts->{erase} )");
119      
120        # resolve metadata for syncing requested resource
121        my $node_target = $nodemapping->{$node_source};
122        my $mapping = $propmapping->{$node_source};
123        
124        if (!$node_target || !$mapping) {
125          # loggger.... "no target, sorry!"
126          print "error while resolving resource metadata", "\n";
127          return;
128        }
129        
130        if ($opts->{erase}) {
131          $self->_erase_all($node_source);
132        }
133      
134        # create new sync object
135        my $sync = Data::Transfer::Sync->new(
136          storages => {
137            L => $self->{bizWorks}->{backend},
138            R => $self->{bizWorks}->{resources},
139          },
140          id_authorities        =>  [qw( L ) ],
141          checksum_authorities  =>  [qw( L ) ],
142          write_protected       =>  [qw( R ) ],
143          verbose               =>  1,
144        );
145        
146        # sync
147        # todo: filter!?
148        $sync->syncNodes( {
149          direction       =>  $mode,                 # | +PUSH | +PULL | -FULL | +IMPORT | -EXPORT
150          method          =>  'checksum',            # | -timestamp | -manual
151          source          =>  "L:$node_source",
152          source_ident    =>  'storage_method:id',
153          source_exclude  =>  [qw( id cs )],
154          target          =>  "R:$node_target",
155          target_ident    =>  'property:oid',
156          mapping         =>  $mapping,
157        } );
158    
159      }
160    
161    
162  =head2 NOTE  =head2 NOTE
163    
164  This module heavily relies on DBI and Tangram, but adds a lot of additional bugs and quirks.  This module heavily relies on DBI and Tangram, but adds a lot of additional bugs and quirks.
165  Please look at their documentation and this code for additional information.  Please look at their documentation and/or this code for additional information.
166    
167    
168    =head1 REQUIREMENTS
169    
170      For full functionality:
171        DBI              from CPAN
172        DBD::mysql       from CPAN
173        Tangram 2.04     from CPAN         (hmmm, 2.04 won't do in some cases)
174        Tangram 2.05     from http://...   (2.05 seems okay but there are also additional patches from our side)
175        Class::Tangram   from CPAN
176        DBD::CSV         from CPAN
177        MySQL::Diff      from http://adamspiers.org/computing/mysqldiff/
178        ... and all their dependencies
179    
180  =cut  =cut
181    
# Line 80  use strict; Line 188  use strict;
188  use warnings;  use warnings;
189    
190  use Data::Storage::Locator;  use Data::Storage::Locator;
191    use Data::Dumper;
192    
193    # TODO: actually implement level (integrate with Log::Dispatch)
194  my $TRACELEVEL = 0;  my $TRACELEVEL = 0;
195    
196  # get logger instance  # get logger instance
# Line 90  sub new { Line 200  sub new {
200    my $invocant = shift;    my $invocant = shift;
201    my $class = ref($invocant) || $invocant;    my $class = ref($invocant) || $invocant;
202    #my @args = normalizeArgs(@_);    #my @args = normalizeArgs(@_);
203      
204    my $arg_locator = shift;    my $arg_locator = shift;
205    my $arg_options = shift;    my $arg_options = shift;
206      
207    #my $self = { STORAGEHANDLE => undef, @_ };    #my $self = { STORAGEHANDLE => undef, @_ };
208    my $self = { STORAGEHANDLE => undef, locator => $arg_locator, options => $arg_options };    my $self = { STORAGEHANDLE => undef, locator => $arg_locator, options => $arg_options };
209    $logger->debug( __PACKAGE__ . "[$self->{locator}->{type}]" . "->new(@_)" );    #$logger->debug( __PACKAGE__ . "[$self->{locator}->{type}]" . "->new(@_)" );
210      $logger->debug( __PACKAGE__ . "[$arg_locator->{type}]" . "->new(@_)" );
211    return bless $self, $class;    return bless $self, $class;
212  }  }
213    
# Line 107  sub AUTOLOAD { Line 218  sub AUTOLOAD {
218    #     - Deep recursion on subroutine "Data::Storage::AUTOLOAD"    #     - Deep recursion on subroutine "Data::Storage::AUTOLOAD"
219    #     - Deep recursion on subroutine "Data::Storage::Handler::Abstract::AUTOLOAD"    #     - Deep recursion on subroutine "Data::Storage::Handler::Abstract::AUTOLOAD"
220    #     - Deep recursion on anonymous subroutine at [...]    #     - Deep recursion on anonymous subroutine at [...]
221    # we also might filter log messages caused by logging itself in "advanced logging of AUTOLOAD calls"    # we also might filter log messages caused by logging to itself in "advanced logging of AUTOLOAD calls"
222        
223    my $self = shift;    my $self = shift;
224    our $AUTOLOAD;    our $AUTOLOAD;
# Line 129  sub AUTOLOAD { Line 240  sub AUTOLOAD {
240        $logstring .= "\t" x $tabcount . "(AUTOLOAD)";        $logstring .= "\t" x $tabcount . "(AUTOLOAD)";
241        # TODO: only ok if logstring doesn't contain        # TODO: only ok if logstring doesn't contain
242        #            e.g. "Data::Storage[Tangram]->insert(SystemEvent=HASH(0x5c0034c))          (AUTOLOAD)"        #            e.g. "Data::Storage[Tangram]->insert(SystemEvent=HASH(0x5c0034c))          (AUTOLOAD)"
243        # but that would be way too specific as long as we don't have an abstract handler for this  ;)        # but that would be _way_ too specific as long as we don't have an abstract handler for this  ;)
244        $logger->debug( $logstring );        $logger->debug( $logstring );
245          #print join('; ', @_);
246      }      }
247            
248    # filtering AUTOLOAD calls    # filtering AUTOLOAD calls and first-time-touch of the actual storage impl
249    if ($self->_filter_AUTOLOAD($method)) {    if ($self->_filter_AUTOLOAD($method)) {
250        #print "_accessStorage\n";
251      $self->_accessStorage();      $self->_accessStorage();
252      $self->{STORAGEHANDLE}->$method(@_);      $self->{STORAGEHANDLE}->$method(@_);
253    }    }
# Line 175  sub _accessStorage { Line 288  sub _accessStorage {
288    
289  sub _createStorageHandle {  sub _createStorageHandle {
290    my $self = shift;    my $self = shift;
   
291    my $type = $self->{locator}->{type};    my $type = $self->{locator}->{type};
292    $logger->debug( __PACKAGE__ .  "[$type]" . "->_createStorageHandle()" );    $logger->debug( __PACKAGE__ .  "[$type]" . "->_createStorageHandle()" );
293    
294    my $pkg = "Data::Storage::Handler::" . $type . "";    my $pkg = "Data::Storage::Handler::" . $type . "";
295        
296    # propagate args to handler    # try to load perl module at runtime
297    # needs some more thoughts! (not only "dbi" to Tangram, when (in future) db is not more the common case)    my $evalstr = "use $pkg;";
298    if ($type eq 'DBI') {    eval($evalstr);
299      use Data::Storage::Handler::DBI;    if ($@) {
300      #my @args = %{$self->{locator}->{dbi}};      $logger->error( __PACKAGE__ .  "[$type]" . "->_createStorageHandle(): $@" );
301      my @args = %{$self->{locator}};      return;
     # create new storage handle  
     $self->{STORAGEHANDLE} = $pkg->new( @args );  
   }  
   if ($type eq 'Tangram') {  
     use Data::Storage::Handler::Tangram;  
     #$self->{STORAGEHANDLE} = $pkg->new( dsn => $self->{locator}->{dbi}->{dsn} );  
     #my @args = %{$self->{locator}->{dbi}};  
     my @args = %{$self->{locator}};  
     # create new storage handle  
     $self->{STORAGEHANDLE} = $pkg->new( @args );  
   
     #$self->{STORAGEHANDLE_UNDERLYING} = $self->{STORAGEHANDLE}->getUnderlyingStorage();  
     #$self->{STORAGEHANDLE_UNDERLYING}->_configureCOREHANDLE();  
302    }    }
303        
304      # build up some additional arguments to pass on
305      #my @args = %{$self->{locator}};
306      my @args = ();
307    
308      # - create new storage handle object
309      # - propagate arguments to handler
310      # - pass locator by reference to be able to store status- or meta-information in it
311      $self->{STORAGEHANDLE} = $pkg->new( locator => $self->{locator}, @args );
312    
313  }  }
314    
315  sub addLogDispatchHandler {  sub addLogDispatchHandler {
# Line 233  sub addLogDispatchHandler { Line 341  sub addLogDispatchHandler {
341  }  }
342    
343  sub removeLogDispatchHandler {  sub removeLogDispatchHandler {
344      my $self = shift;
345        my $self = shift;    my $name = shift;
346        my $name = shift;    #my $logger = shift;
347        #my $logger = shift;    $logger->remove($name);
   
       $logger->remove($name);  
   
348  }  }
349    
350  sub getDbName {  sub getDbName {
# Line 260  sub testDsn { Line 365  sub testDsn {
365      $dbh->disconnect();      $dbh->disconnect();
366      return 1;      return 1;
367    } else {    } else {
368      $logger->error( __PACKAGE__ .  "[$self->{locator}->{type}]" . "->testDsn(): " . "DBI-error: " . $DBI::errstr );      $logger->warning( __PACKAGE__ .  "[$self->{locator}->{type}]" . "->testDsn(): " . "DBI-error: " . $DBI::errstr );
369    }    }
370  }  }
371    
372    sub testAvailability {
373      my $self = shift;
374      my $status = $self->testDsn();
375      $self->{locator}->{status}->{available} = $status;
376      return $status;
377    }
378    
379  sub createDb {  sub createDb {
380    my $self = shift;    my $self = shift;
381    my $dsn = $self->{locator}->{dbi}->{dsn};    my $dsn = $self->{locator}->{dbi}->{dsn};
# Line 326  __END__ Line 438  __END__
438    
439  =head1 DESCRIPTION  =head1 DESCRIPTION
440    
441  Data::Storage is module for a accessing various "data structures" stored inside  Data::Storage is a module for accessing various "data structures" stored inside
442  various "data containers". It sits on top of DBI and/or Tangram.  various "data containers". It sits on top of DBI and/or Tangram.
443    
444    
# Line 341  License or the Artistic License, as spec Line 453  License or the Artistic License, as spec
453    
454  =head1 ACKNOWLEDGEMENTS  =head1 ACKNOWLEDGEMENTS
455    
456  Larry Wall and the C<perl5-porters> for Perl,  Larry Wall for Perl, Tim Bunce for DBI, Jean-Louis Leroy for Tangram and Set::Object,
457  Tim Bunce for DBI, Jean-Louis Leroy for Tangram and Set::Object,  Sam Vilain for Class::Tangram, Jochen Wiedmann and Jeff Zucker for DBD::CSV and related,
458  Sam Vilain for Class::Tangram.  Adam Spiers for MySQL::Diff and all contributors.
459    
460    
461  =head1 SUPPORT / WARRANTY  =head1 SUPPORT / WARRANTY
# Line 354  Data::Storage is free software. IT COMES Line 466  Data::Storage is free software. IT COMES
466  =head1 TODO  =head1 TODO
467    
468    
469  =head2 Handle the following errors/cases:  =head2 BUGS
470    
471    "DBI-Error [Tangram]: DBD::mysql::st execute failed: Unknown column 't1.requestdump' in 'field list'"
472    
473  =head3 "DBI-Error [Tangram]: DBD::mysql::st execute failed: Unknown column 't1.requestdump' in 'field list'"    ... occours when operating on object-attributes not introduced yet:
474      this should be detected and appended/replaced through:
475      "Schema-Error detected, maybe (just) an inconsistency.
476      Please check if your declaration in schema-module "a" matches structure in database "b" or try to run"
477      db_setup.pl --dbkey=import --action=deploy
478    
     ... occours when operating on object-attributes not introduced yet:  
     this should be detected and appended/replaced through:  
     "Schema-Error detected, maybe (just) an inconsistency.  
     Please check if your declaration in schema-module "a" matches structure in database "b" or try to run"  
     db_setup.pl --dbkey=import --action=deploy  
479    
480  =head3 Compare schema (structure diff) with database ...  Compare schema (structure diff) with database ...
481    
482    ... when issuing "db_setup.pl --dbkey=import --action=deploy"    ... when issuing "db_setup.pl --dbkey=import --action=deploy"
483    on a database with an already deployed schema, use an additional "--update" then    on a database with an already deployed schema, use an additional "--update" then
# Line 393  Data::Storage is free software. IT COMES Line 506  Data::Storage is free software. IT COMES
506    automatically and this is believed to be the most common case under normal circumstances.    automatically and this is believed to be the most common case under normal circumstances.
507    
508    
509  =head2 Introduce some features:  =head2 FEATURES
510    
511    - Get this stuff together with UML (Unified Modeling Language) and/or standards from ODMG.    - Get this stuff together with UML (Unified Modeling Language) and/or standards from ODMG.
512    - Make it possible to load/save schemas in XMI (XML Metadata Interchange),    - Make it possible to load/save schemas in XMI (XML Metadata Interchange),
# Line 401  Data::Storage is free software. IT COMES Line 514  Data::Storage is free software. IT COMES
514      Integrate/bundle this with a web-/html-based UML modeling tool or      Integrate/bundle this with a web-/html-based UML modeling tool or
515      some other interesting stuff like the "Co-operative UML Editor" from Uni Darmstadt. (web-/java-based)      some other interesting stuff like the "Co-operative UML Editor" from Uni Darmstadt. (web-/java-based)
516    - Enable Round Trip Engineering. Keep code and diagrams in sync. Don't annoy/bother the programmers.    - Enable Round Trip Engineering. Keep code and diagrams in sync. Don't annoy/bother the programmers.
517    - Add some more handlers:    - Add support for some more handlers/locators to be able to
518      - look at DBD::CSV, Text::CSV, XML::CSV, XML::Excel       access the following standards/protocols/interfaces/programs/apis transparently:
519    - Add some more locations/locators:      +  DBD::CSV (via Data::Storage::Handler::DBI)
520      - PerlDAV: http://www.webdav.org/perldav/     (-) Text::CSV, XML::CSV, XML::Excel
521    - Move to t3, use InCASE      -  MAPI
522        -  LDAP
523        -  DAV (look at PerlDAV: http://www.webdav.org/perldav/)
524        -  Mbox (use formail for seperating/splitting entries/nodes)
525        -  Cyrus (cyrdeliver - what about cyrretrieve (export)???)
526        -  use File::DiffTree, use File::Compare
527        -  Hibernate
528        -  "Win32::UserAccountDb"
529        -  "*nix::UserAccountDb"
530        -  .wab - files (Windows Address Book)
531        -  .pst - files (Outlook Post Storage?)
532        -  XML (e.g. via XML::Simple?)
533      - Move to t3, look at InCASE
534    
535    
536  =head3 Links:  =head3 LINKS / REFERENCES
537    
538    Specs:    Specs:
539      UML 1.3 Spec: http://cgi.omg.org/cgi-bin/doc?ad/99-06-08.pdf      UML 1.3 Spec: http://cgi.omg.org/cgi-bin/doc?ad/99-06-08.pdf
# Line 434  Data::Storage is free software. IT COMES Line 559  Data::Storage is free software. IT COMES
559      (Dia (free): http://www.lysator.liu.se/~alla/dia/)      (Dia (free): http://www.lysator.liu.se/~alla/dia/)
560      UMLet (free, university): http://www.swt.tuwien.ac.at/umlet/index.html      UMLet (free, university): http://www.swt.tuwien.ac.at/umlet/index.html
561      Voodoo (free): http://voodoo.sourceforge.net/      Voodoo (free): http://voodoo.sourceforge.net/
562        Umbrello UML Modeller: http://uml.sourceforge.net/
563    
564    UML Tools:    UML Tools:
565      http://www.objectsbydesign.com/tools/umltools_byPrice.html      http://www.objectsbydesign.com/tools/umltools_byPrice.html

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.8

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