Annotation of loncom/metadata_database/LONCAPA/lonmetadata.pm, revision 1.2
1.1 matthew 1: # The LearningOnline Network with CAPA
2: #
1.2 ! matthew 3: # $Id: lonmetadata.pm,v 1.1 2004/01/12 15:07:08 matthew Exp $
1.1 matthew 4: #
5: # Copyright Michigan State University Board of Trustees
6: #
7: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
8: #
9: # LON-CAPA is free software; you can redistribute it and/or modify
10: # it under the terms of the GNU General Public License as published by
11: # the Free Software Foundation; either version 2 of the License, or
12: # (at your option) any later version.
13: #
14: # LON-CAPA is distributed in the hope that it will be useful,
15: # but WITHOUT ANY WARRANTY; without even the implied warranty of
16: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17: # GNU General Public License for more details.
18: #
19: # You should have received a copy of the GNU General Public License
20: # along with LON-CAPA; if not, write to the Free Software
21: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22: #
23: # /home/httpd/html/adm/gpl.txt
24: #
25: # http://www.lon-capa.org/
26: #
27: ######################################################################
28:
29: package LONCAPA::lonmetadata;
30:
31: use strict;
32: use DBI;
33:
34: ######################################################################
35: ######################################################################
36:
37: =pod
38:
39: =head1 Name
40:
41: lonmetadata
42:
43: =head1 Synopsis
44:
45: lonmetadata holds a description of the metadata table and provides
46: wrappers for the storage and retrieval of metadata to/from the database.
47:
48: =head1 Description
49:
50: =head1 Methods
51:
52: =over 4
53:
54: =cut
55:
56: ######################################################################
57: ######################################################################
58:
59: =pod
60:
61: =item Old table creation command
62:
63: CREATE TABLE IF NOT EXISTS metadata
64: (title TEXT,
65: author TEXT,
66: subject TEXT,
67: url TEXT,
68: keywords TEXT,
69: version TEXT,
70: notes TEXT,
71: abstract TEXT,
72: mime TEXT,
73: language TEXT,
74: creationdate DATETIME,
75: lastrevisiondate DATETIME,
76: owner TEXT,
77: copyright TEXT,
78:
79: FULLTEXT idx_title (title),
80: FULLTEXT idx_author (author),
81: FULLTEXT idx_subject (subject),
82: FULLTEXT idx_url (url),
83: FULLTEXT idx_keywords (keywords),
84: FULLTEXT idx_version (version),
85: FULLTEXT idx_notes (notes),
86: FULLTEXT idx_abstract (abstract),
87: FULLTEXT idx_mime (mime),
88: FULLTEXT idx_language (language),
89: FULLTEXT idx_owner (owner),
90: FULLTEXT idx_copyright (copyright))
91:
92: TYPE=MYISAM;
93:
94: =cut
95:
96: ######################################################################
97: ######################################################################
98: my @Metadata_Table_Description =
99: (
100: { name => 'title', type=>'TEXT'},
101: { name => 'author', type=>'TEXT'},
102: { name => 'subject', type=>'TEXT'},
103: { name => 'url', type=>'TEXT', restrictions => 'NOT NULL' },
104: { name => 'keywords', type=>'TEXT'},
105: { name => 'version', type=>'TEXT'},
106: { name => 'notes', type=>'TEXT'},
107: { name => 'abstract', type=>'TEXT'},
108: { name => 'mime', type=>'TEXT'},
109: { name => 'language', type=>'TEXT'},
110: { name => 'creationdate', type=>'DATETIME'},
111: { name => 'lastrevisiondate', type=>'DATETIME'},
112: { name => 'owner', type=>'TEXT'},
113: { name => 'copyright', type=>'TEXT'},
114: #--------------------------------------------------
115: { name => 'dependencies', type=>'TEXT'},
116: { name => 'modifyinguser', type=>'TEXT'},
117: { name => 'authorspace', type=>'TEXT'},
118: { name => 'lowestgradelevel', type=>'INT'},
119: { name => 'highestgradelevel', type=>'INT'},
120: { name => 'standards', type=>'TEXT'},
121: { name => 'count', type=>'INT'},
122: { name => 'course', type=>'INT'},
123: { name => 'course_list', type=>'TEXT'},
124: { name => 'goto', type=>'INT'},
125: { name => 'goto_list', type=>'TEXT'},
126: { name => 'comefrom', type=>'INT'},
127: { name => 'comefrom_list', type=>'TEXT'},
128: { name => 'sequsage', type=>'INT'},
129: { name => 'sequsage_list', type=>'TEXT'},
130: { name => 'stdno', type=>'INT'},
131: { name => 'stdno_list', type=>'TEXT'},
132: { name => 'avetries', type=>'FLOAT'},
133: { name => 'avetries_list', type=>'TEXT'},
134: { name => 'difficulty', type=>'FLOAT'},
135: { name => 'difficulty_list',type=>'TEXT'},
136: { name => 'clear', type=>'FLOAT'},
137: { name => 'technical', type=>'FLOAT'},
138: { name => 'correct', type=>'FLOAT'},
139: { name => 'helpful', type=>'FLOAT'},
140: { name => 'depth', type=>'FLOAT'},
141: { name => 'hostname', type=> 'TEXT'},
142: #--------------------------------------------------
143: );
144:
145: my @Fulltext_indicies = qw/
146: title
147: author
148: subject
149: url
150: keywords
151: version
152: notes
153: abstract
154: mime
155: language
156: owner
157: copyright/;
158:
159: ######################################################################
160: ######################################################################
161:
162: =pod
163:
164: =item &describe_metadata_storage
165:
166: Input: None
167:
1.2 ! matthew 168: Returns: An array of hash references describing the columns and indicies
! 169: of the metadata table(s).
1.1 matthew 170:
171: =cut
172:
173: ######################################################################
174: ######################################################################
175: sub describe_metadata_storage {
176: return (\@Metadata_Table_Description,\@Fulltext_indicies);
177: }
178:
179: ######################################################################
180: ######################################################################
181:
182: =pod
183:
184: =item create_metadata_storage()
185:
186: Inputs: None
187:
188: Returns: A perl string which, when executed by MySQL, will cause the
189: metadata storage to be initialized.
190:
191: =cut
192:
193: ######################################################################
194: ######################################################################
195: sub create_metadata_storage {
196: my $tablename = 'metadata';
197: my $request = "CREATE TABLE IF NOT EXISTS ".$tablename." ";
198: #
199: # Process the columns (this code is stolen from lonmysql.pm)
200: my @Columns;
201: my $col_des; # mysql column description
202: foreach my $coldata (@Metadata_Table_Description) {
203: my $column = $coldata->{'name'};
204: $col_des = '';
205: if (lc($coldata->{'type'}) =~ /(enum|set)/) { # 'enum' or 'set'
206: $col_des.=$column." ".$coldata->{'type'}."('".
207: join("', '",@{$coldata->{'values'}})."')";
208: } else {
209: $col_des.=$column." ".$coldata->{'type'};
210: if (exists($coldata->{'size'})) {
211: $col_des.="(".$coldata->{'size'}.")";
212: }
213: }
214: # Modifiers
215: if (exists($coldata->{'restrictions'})){
216: $col_des.=" ".$coldata->{'restrictions'};
217: }
218: if (exists($coldata->{'default'})) {
219: $col_des.=" DEFAULT '".$coldata->{'default'}."'";
220: }
221: $col_des.=' AUTO_INCREMENT' if (exists($coldata->{'auto_inc'}) &&
222: ($coldata->{'auto_inc'} eq 'yes'));
223: $col_des.=' PRIMARY KEY' if (exists($coldata->{'primary_key'}) &&
224: ($coldata->{'primary_key'} eq 'yes'));
225: } continue {
226: # skip blank items.
227: push (@Columns,$col_des) if ($col_des ne '');
228: }
229: foreach my $colname (@Fulltext_indicies) {
230: my $text = 'FULLTEXT idx_'.$colname.' ('.$colname.')';
231: push (@Columns,$text);
232: }
233: $request .= "(".join(", ",@Columns).") ";
234: return $request;
235: }
236:
237: ######################################################################
238: ######################################################################
239:
240: =pod
241:
242: =item store_metadata()
243:
244: Inputs: database handle ($dbh) and a hash or hash reference containing the
245: metadata for a single resource.
246:
247: Returns: 1 on success, 0 on failure to store.
248:
249: =cut
250:
251: ######################################################################
252: ######################################################################
1.2 ! matthew 253: {
! 254: ##
! 255: ## WARNING: The following cleverness may cause trouble in cases where
! 256: ## the dbi connection is dropped and recreated - a stale statement
! 257: ## handler may linger around and cause trouble.
! 258: ##
! 259: ## In most scripts, this will work fine. If the dbi is going to be
! 260: ## dropped and (possibly) later recreated, call &clear_sth. Yes it
! 261: ## is annoying but $sth appearantly does not have a link back to the
! 262: ## $dbh, so we can't check our validity.
! 263: ##
! 264: my $sth = undef;
! 265:
! 266: sub create_statement_handler {
! 267: my $dbh = shift();
! 268: my $request = 'INSERT INTO metadata VALUES(';
! 269: foreach (@Metadata_Table_Description) {
! 270: $request .= '?,';
! 271: }
! 272: chop $request;
! 273: $request.= ')';
! 274: $sth = $dbh->prepare($request);
! 275: return;
! 276: }
! 277:
! 278: sub clear_sth { $sth=undef; }
! 279:
1.1 matthew 280: sub store_metadata {
1.2 ! matthew 281: my $dbh = shift();
! 282: my $errors = '';
! 283: if (! defined($sth)) {
! 284: &create_statement_handler($dbh);
! 285: }
! 286: my $successcount = 0;
! 287: while (my $mdata = shift()) {
! 288: next if (ref($mdata) ne "HASH");
! 289: my @MData;
! 290: foreach my $field (@Metadata_Table_Description) {
! 291: if (exists($mdata->{$field->{'name'}})) {
! 292: push(@MData,$mdata->{$field->{'name'}});
! 293: } else {
! 294: push(@MData,undef);
! 295: }
! 296: }
! 297: $sth->execute(@MData);
! 298: if (! $sth->err) {
! 299: $successcount++;
! 300: } else {
! 301: $errors = join(',',$errors,$sth->errstr);
! 302: }
! 303: }
! 304: if (wantarray()) {
! 305: return ($successcount,$errors);
! 306: } else {
! 307: return $successcount;
! 308: }
! 309: }
1.1 matthew 310:
311: }
312:
313: ######################################################################
314: ######################################################################
315:
316: =pod
317:
318: =item lookup_metadata()
319:
320: Inputs: database handle ($dbh) and a hash or hash reference containing
321: metadata which will be used for a search.
322:
1.2 ! matthew 323: Returns: scalar with error string on failure, array reference on success.
! 324: The array reference is the same one returned by $sth->fetchall_arrayref().
1.1 matthew 325:
326: =cut
327:
328: ######################################################################
329: ######################################################################
1.2 ! matthew 330: sub lookup_metadata {
! 331: my ($dbh,$condition,$fetchparameter) = @_;
! 332: my $error;
! 333: my $returnvalue=[];
! 334: my $request = 'SELECT * FROM metadata';
! 335: if (defined($condition)) {
! 336: $request .= ' WHERE '.$condition;
! 337: }
! 338: my $sth = $dbh->prepare($request);
! 339: if ($sth->err) {
! 340: $error = $sth->errstr;
! 341: }
! 342: if (! $error) {
! 343: $sth->execute();
! 344: if ($sth->err) {
! 345: $error = $sth->errstr;
! 346: } else {
! 347: $returnvalue = $sth->fetchall_arrayref($fetchparameter);
! 348: if ($sth->err) {
! 349: $error = $sth->errstr;
! 350: }
! 351: }
! 352: }
! 353: return ($error,$returnvalue);
! 354: }
1.1 matthew 355:
356: ######################################################################
357: ######################################################################
358:
359: =pod
360:
361: =item delete_metadata()
362:
363:
364:
365: =cut
366:
367: ######################################################################
368: ######################################################################
369: sub delete_metadata {}
370:
371: ######################################################################
372: ######################################################################
373:
374: 1;
375:
376: __END__;
377:
378: =pod
379:
380: =back
381:
382: =cut
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>