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