From: <cwi...@cw...> - 2003-11-14 02:48:55
|
* Andrew Hurst (hur...@ll...) [031112 13:36]: > Finally back to work with OpenInteract, I've got a question. I'm > working on a document management system, and the documents will be > broken up into pages and paragraphs. The general idea is: > > Document 1->N DocumentPage 1->N DocumentParagraph. > > Relevant table structure: > Document has a document_id > DocumentPage has a document_page_id, and document_id > DocumentParagraph has a document_paragraph_id and a document_page_id Got it so far... > What I would like to do, is represent this link somehow in the > spops.perl, but I'm not exactly sure how. I want to be able to be > using a document object, and get the list of documentPage objects > associated with it by just doing: > @doc_pages = @{ $document->document_pages }; > I've looked into has_a, and links_to, but they don't seem to do > exactly what I need. Specifically it looks as if I need to keep the > id of the DocumentPage object that is 'had' by the Document object in > the Document table. Is there a way to specify 'linked_by' > relationships? Actually, the 'links_to' will do this as a side effect, although you won't be able to properly use the _add and _remove functionality. See the SPOPS configurations for theme and theme_property (pkg/base_theme-x.xx/conf/spops.perl) as an example, where: Theme (theme_id) -> Theme Property (each w/theme_id) links_to > In writing this I've realized that this could be a huge performance > hit for big documents with lots of pages and paragraphs (the one that > I'm designing this for has about 99 pages in Word). I might just > have to write a few functions to fetch this information manually and > only set it if needed... If there's any question about performance and fetching lots and lots of objects at a time, particularly when I'm dealing with them in chunks or in a stream, then I usually write it by hand. Like the following when you're dealing with the items as a stream: package My::Document; sub document_pages { my ( $self ) = @_; my $iterator = eval { My::DocumentPage->fetch_iterator({ where => 'document_id = ?', value => [ $self->id ], order => 'page_num' }) }; if ( $@ ) { ... } return $iterator; } Then you'd deal with each page: $iterator = $document->document_pages; while ( $iterator->has_next ) { my $page = $iterator->get_next; print "Page $page->{page_num}: $page->{title}\n"; } You could even modify this to do a parameterized stream vs. list: sub document_pages { my ( $self, $return_type ) = @_; $return_type ||= 'stream'; my $method = ( $return_type eq 'stream' ) ? 'fetch_iterator' : 'fetch_group'; my $values = eval { My::DocumentPage->$method({ ... These are so easy to write and the underlying assumptions for relationships tend to change so infrequently that it's usually best to go ahead and write the implementation if you have any questions about it. Chris -- Chris Winters (ch...@cw...) Building enterprise-capable snack solutions since 1988. |