PyXR

c:\projects\bitpim\src \ vtab_media.py



0001 ### BITPIM
0002 ###
0003 ### Copyright (C) 2007 Joe Pham <djpham@bitpim.org>
0004 ###
0005 ### This program is free software; you can redistribute it and/or modify
0006 ### it under the terms of the BitPim license as detailed in the LICENSE file.
0007 ###
0008 ### $Id: vtab_media.py 4155 2007-03-17 04:07:42Z djpham $
0009 
0010 """
0011 An apsw compatible module that implements a virtual table that stores media
0012 data as native system files.
0013 """
0014 # System modules
0015 import glob
0016 import os
0017 import os.path
0018 
0019 # BitPim moduless
0020 import database
0021 
0022 class Media(database.ModuleBase):
0023     """
0024     Module to implements a virtual table that stores media data as native system
0025     files.
0026     The table has 2 fiels: __rowid__ and mediadata
0027     This class maintains its own rowid, cursor, and constraints parameters.
0028     The data of each row is stored in a file named Fxxxxxxx, where
0029     xxxxxxx is the rowid starting with 1 ie (F0000001, F0000002, etc)
0030     """
0031 
0032     def __init__(self, pathname):
0033         """
0034         @params pathname: full path in which to stores data files
0035         """
0036         super(Media, self).__init__(('data',))
0037         # make sure the path exists
0038         if not os.path.exists(pathname):
0039             os.makedirs(pathname)
0040         self.pathname=os.path.abspath(pathname)
0041         self.rowidfilename=os.path.join(self.pathname, 'rowid')
0042         self.getnextrowid()
0043         self.filenames=[]
0044         self.cursor=None
0045 
0046     def getnextrowid(self):
0047         """
0048         Return the next row ID from a file called rowid
0049         """
0050         try:
0051             id=file(self.rowidfilename, 'rt').read()
0052             self.rowid=int(id)
0053         except IOError:
0054             # file does not exist
0055             self.rowid=1
0056             self.saverowid(1)
0057     def incrementrowid(self):
0058         # increment the next row ID by 1
0059         self.rowid+=1
0060         self.saverowid(self.rowid)
0061     def saverowid(self, id):
0062         file(self.rowidfilename, 'wt').write(str(id))
0063     def filenamefromid(self, id):
0064         # return a full path name based on the row ID
0065         return os.path.join(self.pathname, 'F%07d'%id)
0066     def idfromfilename(self, filename):
0067         return int(os.path.basename(filename)[1:])
0068 
0069     def BestIndex(self, constraints, orderby):
0070         """
0071         Provide information on how to best access this table.
0072         Must be overriden by subclass.
0073         @params constraints: a tuple of (column #, op) defining a constraints
0074         @params orderby: a tuple of (column #, desc) defining the order by
0075         @returns a tuple of up to 5 values:
0076             0: aConstraingUsage: a tuple of the same size as constraints.
0077                 Each item is either None, argv index(int), or (argv index, omit(Bool)).
0078             1: idxNum(int)
0079             2: idxStr(string)
0080             3: orderByConsumed(Bool)
0081             4: estimatedCost(float)
0082 
0083         Todo: store the constraints for subsequent evaluation, and tell
0084             sqlite to pass the constraints parameters to Filter.
0085         """
0086         pass
0087     def Filter(self, idxNum, idxStr, argv):
0088         """
0089         Begin a search of a virtual table.
0090         @params idxNum: int value passed by BestIndex
0091         @params idxStr: string valued passed by BestIndex
0092         @params argv: constraint parameters requested by BestIndex
0093         @returns: None
0094 
0095         Todo: evaluate actual constraints, will let sqlite do the orderby.
0096         """
0097         self.filenames=glob.glob(os.path.join(self.pathname,
0098                                               'F[0-9][0-9][0-9][0-9][0-9][0-9][0-9]'))
0099         if self.filenames:
0100             self.cursor=0
0101         else:
0102             self.cursor=None
0103     def Eof(self):
0104         """
0105         Determines if the current cursor points to a valid row.
0106         @returns: False if valid row, True otherwise
0107         """
0108         return self.cursor is None or self.cursor>=len(self.filenames)
0109     def Column(self, N):
0110         """
0111         Find the value for the N-th column of the current row.
0112         @params N: the N-th column
0113         @returns: value of the N-th column
0114         We only have 2 columns: __rowid__ and mediadata
0115         """
0116         filename=self.filenames[self.cursor]
0117         if N==0:
0118             # __rowid__
0119             return self.idfromfilename(filename)
0120         else:
0121             # mediadata
0122             return buffer(file(filename, 'rb').read())
0123     def Next(self):
0124         """
0125         Move the cursor to the next row.
0126         @returns: None
0127         """
0128         self.cursor+=1
0129     def Rowid(self):
0130         """
0131         Return the rowid of the current row.
0132         @returns: the rowid(int) of the current row.
0133         """
0134         return self.Column(0)
0135     def UpdateDeleteRow(self, rowid):
0136         """
0137         Delete row rowid
0138         @params rowid: rowid to delete
0139         @returns: None
0140         """
0141         # delete the file
0142         os.remove(self.filenamefromid(rowid))
0143     def UpdateInsertRow(self, rowid, fields):
0144         """
0145         Insert a new row of data into the table
0146         @params rowid: if not None, use this rowid.  If None, create a new rowid
0147         @params fields: a tuple of the field values in the order declared in
0148             Create/Connet
0149         @returns: rowid of the new row.
0150         """
0151         if rowid is None:
0152             rowid=self.rowid
0153             self.incrementrowid()
0154         file(self.filenamefromid(rowid), 'wb').write(fields[1])
0155         return rowid
0156     def UpdateChangeRow(self, rowid, newrowid, fields):
0157         """
0158         Change the row of the current rowid with the new rowid and new values
0159         @params rowid: rowid of the current row
0160         @params newrowid: new rowid
0161         @params fields: a tuple of the field values in the order declared in
0162             Create/Connect
0163         @returns: rowid of the new row
0164         """
0165         os.remove(self.filenamefromid(rowid))
0166         file(self.filenamefromid(newrowid), 'wb').write(fields[1])
0167         return newrowid
0168 

Generated by PyXR 0.9.4