1
2
3
4
5
6 import os
7 import re
8 import errno
9 import time
10 import mdinterface
11 from mdinterface import CommandException, MDInterface
12 from mdparser import MDParser
13 from mdtable import MDTable
14 from diskutils import RLock, getLast, readLast, write, remove
15
16 DEBUG = False
17
19 age = arg
20 for name in files:
21 if name != 'LOCK':
22 continue
23 filename = os.path.join(directory, name)
24 mtime = os.stat(filename).st_mtime
25 if age > 0 and mtime > age:
26 continue
27 os.remove(filename)
28
29
31 (age, root, lines) = arg
32 for name in files:
33 if name != 'LOCK':
34 continue
35 filename = os.path.join(directory, name)
36 mtime = os.stat(filename).st_mtime
37 if age > 0 and mtime > age:
38 continue
39 line = filename[len(root)-1:]
40 line = os.path.normpath(line)
41 line = line[0: len(line)-5]
42 if len(line) == 0:
43 line = "/"
44 line = os.path.normpath(line)
45 lines.append(line)
46
47
50 """ works the way a good mkdir should :)
51 - already exists, silently complete
52 - regular file in the way, raise an exception
53 - parent directory(ies) does not exist, make them as well
54 """
55 if os.path.isdir(newdir):
56 pass
57 elif os.path.isfile(newdir):
58 raise mdinterface.CommandException(16, "Directory exists")
59 try:
60 os.makedirs(newdir)
61 except OSError, e:
62 if e[0] == errno.EPERM or e[0] == errno.EACCES:
63 raise mdinterface.CommandException(4, "Could not create dir: Permission denied")
64 else:
65 raise mdinterface.CommandException(16, "Directory existed")
66
67
68 - def __init__(self, root,
69 blocklength = 1000,
70 cache_size = 100000,
71 tries_limit = 200):
72 self.root = os.path.normpath(root)
73 self.blocklength = blocklength
74 self.cache_size = cache_size
75 self.tries_limit = tries_limit
76 self.rows=[]
77 self.tables = {}
78 self.currentDir = '/'
79 self.loaded_tables = {}
80 self.upload_cmd = {}
81 self.transaction_in_prgs = False
82 self.sequence_reserve = {}
83
84
88
89
91 if DEBUG: print '__absolutePath for ', table
92 if len(table) and table[0] == '/':
93 prefix = ''
94 else:
95 prefix = self.currentDir + '/'
96 table = os.path.normpath(prefix + table).replace(os.sep, '/')
97 if DEBUG: print '__absolutePath: returning', table
98 return table
99
100
102 path = os.path.normpath(self.root + '/' + path)
103 if DEBUG: print '__systemPath returns: ', path
104 return path
105
106
108 if not self.transaction_in_prgs:
109 self.tables = {}
110
111
124
125
131
132
133 - def __addEntry(self, mdtable, entry, attrs, values):
134 if mdtable.entries.has_key(entry):
135 raise CommandException(15, "Entry exists")
136
137 e=[''] * (len(mdtable.attributes)+1)
138 e[0]=entry
139 for i in range(0, len(attrs)):
140 e[mdtable.attributeDict[attrs[i]]+1] = values[i]
141 mdtable.entries.append(e)
142
143
145 dirname = self.__systemPath(table)
146 if not os.path.isdir(dirname):
147 raise CommandException(1, 'File or directory does not exist')
148 if table not in self.loaded_tables:
149 self.loaded_tables[table] = MDTable(dirname,
150 blocklength = self.blocklength,
151 cache_size = self.cache_size,
152 tries_limit = self.tries_limit)
153 return self.loaded_tables[table]
154
155
157 if not self.transaction_in_prgs:
158 for table in self.tables:
159 self.tables[table].unlock()
160
161
163 return len(self.rows) == 0
164
165
182
183
203
204
221
222
223 - def addEntry(self, file, keys, values):
224 self.__initTransaction()
225 try:
226 tablename, entry = os.path.split(file)
227 mdtable, tablename = self.__loadTable(tablename, True)
228 self.__addEntry(mdtable, entry, keys, values)
229 self.__saveTable(tablename)
230 finally:
231 self.releaseAllLocks()
232
233
235 self.__initTransaction()
236 try:
237 if self.__isDir(file):
238 tablename = file
239 entry = '*'
240 else:
241 tablename, entry = os.path.split(file)
242 mdtable, tablename = self.__loadTable(tablename)
243 self.rows = []
244 pattern = entry.replace('*', '.*')
245 pattern = pattern.replace('?', '.')
246 for i in range(0, len(mdtable.entries)):
247 e = mdtable.entries[i]
248 r = re.match(pattern, e[0])
249 if r and r.group(0) == e[0]:
250 row = []
251 row.append(e[0])
252 for j in range(0, len(attrs)):
253 index = mdtable.attributeDict[attrs[j]]
254 row.append(e[index+1])
255 self.rows.append(row)
256 finally:
257 self.releaseAllLocks()
258
259
260 - def getEntry(self):
261 e = self.rows.pop(0)
262
263 return (e[0], e[1:])
264
265
270
271
273 if DEBUG: print 'listEntries ', dirname
274 self.__initTransaction()
275 try:
276 dirname = self.__absolutePath(dirname)
277 if self.__isDir(dirname):
278 entry = "*"
279 else:
280 dirname, entry = os.path.split(dirname)
281
282
283 dirs = os.listdir(self.__systemPath(dirname))
284 for d in dirs:
285 if self.__isDir(dirname + '/' +d):
286 row = []
287 row.append(dirname + '/' +d)
288 row.append('collection')
289 self.rows.append(row)
290
291
292 mdtable, dirname = self.__loadTable(dirname)
293 pattern = entry.replace('*', '.*')
294 pattern = pattern.replace('?', '.')
295 for i in range(0, len(mdtable.entries)):
296 e = mdtable.entries[i]
297 r = re.match(pattern, e[0])
298 if r and r.group(0) == e[0]:
299 row = []
300 row.append(e[0])
301 row.append('entry')
302 self.rows.append(row)
303 finally:
304 self.releaseAllLocks()
305
306
327
328
329 - def rm(self, path):
330 if DEBUG: print 'rm ', path
331 self.__initTransaction()
332 try:
333 dirname, entry = os.path.split(path)
334 mdtable, dirname = self.__loadTable(dirname, True)
335 pattern = entry.replace('*', '.*')
336 pattern = pattern.replace('?', '.')
337 for i in range(len(mdtable.entries)-1, -1, -1):
338 e = mdtable.entries[i]
339 r = re.match(pattern, e[0])
340 if r and r.group(0) == e[0]:
341 del mdtable.entries[i]
342 self.__saveTable(dirname)
343 finally:
344 self.releaseAllLocks()
345
346
368
369
371
372
373
374 def next(name, reserve):
375 dirname, seq = os.path.split(name)
376 name = self.__systemPath(self.__absolutePath(dirname) + '/SEQ'+seq)
377 lockfile = name+".LOCK"
378 lock = RLock(lockfile)
379 if lock.acquire():
380 try:
381 try:
382 entries = readLast(name)
383 except (OSError,IOError), e:
384 raise CommandException(17, "Not a sequence: " + str(e))
385 if not (len(entries)==1 and len(entries[0])==3):
386 raise CommandException(17, "Not a sequence: " + str(e))
387 start, increment, now = entries[0]
388 newval = str(int(now) + int(increment) * reserve)
389 entry = [start, increment, newval]
390 try:
391 write([entry], name)
392 except (OSError,IOError), e:
393 raise CommandException(17, "sequenceNext error: " + str(e))
394 return (now, increment, newval)
395 finally:
396 lock.release()
397 else:
398 raise CommandException(9, "Cannot lock %s" % name)
399
400 if reserve > 1:
401 try:
402 if name in self.sequence_reserve:
403 now, increment, reserved = self.sequence_reserve[name]
404 else:
405 now, increment, reserved = map(int, next(name, reserve))
406 self.sequence_reserve[name] = [now, increment, reserved]
407 newval = now + increment
408 if newval >= reserved:
409 del self.sequence_reserve[name]
410 else:
411 self.sequence_reserve[name][0] = newval
412 return str(now)
413 except Exception, e:
414 raise CommandException(17, "sequenceNext error: " + str(e))
415 else:
416 return next(name, reserve)[0]
417
418
436
437
448
449
451 if DEBUG: print 'selectAttr ', attrs, query
452 self.__initTransaction()
453 try:
454 self.rows = []
455 tList = []
456 aList = []
457 for a in attrs:
458 table, attr = a.split(':', 1)
459 mdtable, table = self.__loadTable(table)
460 tList.append(table)
461 aList.append(attr)
462
463 parser = MDParser(query, self.tables,
464 self.currentDir, self.__loadTable)
465
466
467 parser.parseWhereClause()
468 allTables = []
469 iterations = 0
470 for k, v in self.tables.iteritems():
471 v.initRowPointer()
472 allTables.append(v)
473 if iterations == 0:
474 iterations = len(v.entries)
475 else:
476 iterations = iterations * len(v.entries)
477
478 for i in range(0, iterations):
479 if parser.parseWhereClause():
480 row = []
481 for j in range(0, len(attrs)):
482 t = self.tables[tList[j]]
483 if aList[j] == "FILE":
484 index = 0
485 else:
486 index = t.attributeDict[aList[j]]+1
487 row.append(t.entries[t.currentRow][index])
488 self.rows.append(row)
489 for j in range (0, len(allTables)):
490 if allTables[j].currentRow < 0:
491 continue
492 allTables[j].currentRow = allTables[j].currentRow + 1
493 if allTables[j].currentRow < len(allTables[j].entries):
494 break
495 allTables[j].currentRow = 0
496 finally:
497 self.releaseAllLocks()
498
499
501
502 return self.rows.pop(0)
503
504
505 - def updateAttr(self, pattern, updateExpr, condition):
506 if DEBUG: print 'updateAttr ', pattern, updateExpr, condition
507 self.__initTransaction()
508 try:
509 dirname = self.__absolutePath(pattern)
510 if self.__isDir(dirname):
511 entry = "*"
512 else:
513 dirname, entry = os.path.split(dirname)
514 mdtable, tablename = self.__loadTable(dirname, True)
515 pattern = entry.replace('*', '.*')
516 pattern = pattern.replace('?', '.')
517
518 parser = MDParser(condition, self.tables,
519 tablename, self.__loadTable)
520
521
522 parser.parseWhereClause()
523
524
525 expressions = []
526 for e in updateExpr:
527 var, exp = self.splitUpdateClause(e)
528 index = mdtable.attributeDict[var]+1
529 p = MDParser(exp, self.tables, tablename,
530 self.__loadTable)
531 parser.parseWhereClause()
532 expressions.append( (index, exp, p) )
533
534
535
536 allTables = []
537 iterations = 0
538 for k, v in self.tables.iteritems():
539 v.initRowPointer()
540 if len(v.entries) == 0:
541 continue
542 allTables.append(v)
543 if iterations == 0:
544 iterations = len(v.entries)
545 else:
546 iterations = iterations * len(v.entries)
547
548
549
550 for i in range(0, iterations):
551 e = mdtable.entries[mdtable.currentRow]
552 r = re.match(pattern, e[0])
553 if r and r.group(0) == e[0]:
554 if parser.parseWhereClause():
555 for j in range (0, len(expressions)):
556 index, exp, p = expressions[j]
557 value = p.parseStatement()
558 e[index] = value
559 mdtable.entries[mdtable.currentRow] = e
560 for j in range (0, len(allTables)):
561 allTables[j].currentRow = allTables[j].currentRow + 1
562 if allTables[j].currentRow < len(allTables[j].entries):
563 break
564 else:
565 allTables[j].currentRow = 0
566 self.__saveTable(tablename)
567 finally:
568 self.releaseAllLocks()
569
570
571 - def setAttr(self, file, keys, values):
589
590
592 return self.currentDir
593
594
600
601
602 - def upload(self, collection, attributes):
603 self.transaction()
604 mdtable, tablename = self.__loadTable(collection, True)
605 self.upload_cmd['collection'] = tablename
606 self.upload_cmd['attributes'] = attributes
607
608
609 - def put(self, file, values):
610 if not self.transaction_in_prgs:
611 raise CommandException(9, "Could not abort No transaction in progress. Command was: abort")
612 elif len(values)!=len(self.upload_cmd['attributes']):
613 raise CommandException(3, "Illegal command")
614 tablename, entry = os.path.split(file)
615 if tablename:
616 assert(tablename == self.upload_cmd['collection'])
617 mdtable = self.tables[self.upload_cmd['collection']]
618 attrs = self.upload_cmd['attributes']
619 self.__addEntry(mdtable, entry, attrs, values)
620
621
623 if not self.transaction_in_prgs:
624 raise CommandException(9, "Could not abort No transaction in progress. Command was: abort")
625 try:
626 self.transaction_in_prgs = False
627 self.upload_cmd = {}
628 finally:
629 self.releaseAllLocks()
630
631
633 if not self.transaction_in_prgs:
634 raise CommandException(9, "Could not commit No transaction in progress. Command was: commit")
635 try:
636 self.transaction_in_prgs = False
637 for table in self.tables:
638 self.__saveTable(table)
639 finally:
640 self.releaseAllLocks()
641
642
644 self.__initTransaction()
645 if not self.transaction_in_prgs:
646 self.transaction_in_prgs = True
647
648
649
650
651
652
657
658
659
667