1## @file
2# This file is used to create/update/query/erase table for files
3#
4# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
5# This program and the accompanying materials
6# are licensed and made available under the terms and conditions of the BSD License
7# which accompanies this distribution.  The full text of the license may be found at
8# http://opensource.org/licenses/bsd-license.php
9#
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12#
13
14##
15# Import Modules
16#
17import Common.LongFilePathOs as os
18
19import Common.EdkLogger as EdkLogger
20from CommonDataClass import DataClass
21from CommonDataClass.DataClass import FileClass
22
23## Convert to SQL required string format
24def ConvertToSqlString(StringList):
25    return map(lambda s: "'" + s.replace("'", "''") + "'", StringList)
26
27## TableFile
28#
29# This class defined a common table
30#
31# @param object:     Inherited from object class
32#
33# @param Cursor:     Cursor of the database
34# @param TableName:  Name of the table
35#
36class Table(object):
37    _COLUMN_ = ''
38    _ID_STEP_ = 1
39    _ID_MAX_ = 0x80000000
40    _DUMMY_ = 0
41
42    def __init__(self, Cursor, Name='', IdBase=0, Temporary=False):
43        self.Cur = Cursor
44        self.Table = Name
45        self.IdBase = int(IdBase)
46        self.ID = int(IdBase)
47        self.Temporary = Temporary
48
49    def __str__(self):
50        return self.Table
51
52    ## Create table
53    #
54    # Create a table
55    #
56    def Create(self, NewTable=True):
57        if NewTable:
58            self.Drop()
59
60        if self.Temporary:
61            SqlCommand = """create temp table IF NOT EXISTS %s (%s)""" % (self.Table, self._COLUMN_)
62        else:
63            SqlCommand = """create table IF NOT EXISTS %s (%s)""" % (self.Table, self._COLUMN_)
64        EdkLogger.debug(EdkLogger.DEBUG_8, SqlCommand)
65        self.Cur.execute(SqlCommand)
66        self.ID = self.GetId()
67
68    ## Insert table
69    #
70    # Insert a record into a table
71    #
72    def Insert(self, *Args):
73        self.ID = self.ID + self._ID_STEP_
74        if self.ID >= (self.IdBase + self._ID_MAX_):
75            self.ID = self.IdBase + self._ID_STEP_
76        Values = ", ".join([str(Arg) for Arg in Args])
77        SqlCommand = "insert into %s values(%s, %s)" % (self.Table, self.ID, Values)
78        EdkLogger.debug(EdkLogger.DEBUG_5, SqlCommand)
79        self.Cur.execute(SqlCommand)
80        return self.ID
81
82    ## Query table
83    #
84    # Query all records of the table
85    #
86    def Query(self):
87        SqlCommand = """select * from %s""" % self.Table
88        self.Cur.execute(SqlCommand)
89        for Rs in self.Cur:
90            EdkLogger.verbose(str(Rs))
91        TotalCount = self.GetId()
92
93    ## Drop a table
94    #
95    # Drop the table
96    #
97    def Drop(self):
98        SqlCommand = """drop table IF EXISTS %s""" % self.Table
99        self.Cur.execute(SqlCommand)
100
101    ## Get count
102    #
103    # Get a count of all records of the table
104    #
105    # @retval Count:  Total count of all records
106    #
107    def GetCount(self):
108        SqlCommand = """select count(ID) from %s""" % self.Table
109        Record = self.Cur.execute(SqlCommand).fetchall()
110        return Record[0][0]
111
112    def GetId(self):
113        SqlCommand = """select max(ID) from %s""" % self.Table
114        Record = self.Cur.execute(SqlCommand).fetchall()
115        Id = Record[0][0]
116        if Id == None:
117            Id = self.IdBase
118        return Id
119
120    ## Init the ID of the table
121    #
122    # Init the ID of the table
123    #
124    def InitID(self):
125        self.ID = self.GetId()
126
127    ## Exec
128    #
129    # Exec Sql Command, return result
130    #
131    # @param SqlCommand:  The SqlCommand to be executed
132    #
133    # @retval RecordSet:  The result after executed
134    #
135    def Exec(self, SqlCommand):
136        EdkLogger.debug(EdkLogger.DEBUG_5, SqlCommand)
137        self.Cur.execute(SqlCommand)
138        RecordSet = self.Cur.fetchall()
139        return RecordSet
140
141    def SetEndFlag(self):
142        self.Exec("insert into %s values(%s)" % (self.Table, self._DUMMY_))
143        #
144        # Need to execution commit for table data changed.
145        #
146        self.Cur.connection.commit()
147
148    def IsIntegral(self):
149        Result = self.Exec("select min(ID) from %s" % (self.Table))
150        if Result[0][0] != -1:
151            return False
152        return True
153
154    def GetAll(self):
155        return self.Exec("select * from %s where ID > 0 order by ID" % (self.Table))
156
157## TableFile
158#
159# This class defined a table used for file
160#
161# @param object:       Inherited from object class
162#
163class TableFile(Table):
164    _COLUMN_ = '''
165        ID INTEGER PRIMARY KEY,
166        Name VARCHAR NOT NULL,
167        ExtName VARCHAR,
168        Path VARCHAR,
169        FullPath VARCHAR NOT NULL,
170        Model INTEGER DEFAULT 0,
171        TimeStamp SINGLE NOT NULL
172        '''
173    def __init__(self, Cursor):
174        Table.__init__(self, Cursor, 'File')
175
176    ## Insert table
177    #
178    # Insert a record into table File
179    #
180    # @param Name:      Name of a File
181    # @param ExtName:   ExtName of a File
182    # @param Path:      Path of a File
183    # @param FullPath:  FullPath of a File
184    # @param Model:     Model of a File
185    # @param TimeStamp: TimeStamp of a File
186    #
187    def Insert(self, Name, ExtName, Path, FullPath, Model, TimeStamp):
188        (Name, ExtName, Path, FullPath) = ConvertToSqlString((Name, ExtName, Path, FullPath))
189        return Table.Insert(
190            self,
191            Name,
192            ExtName,
193            Path,
194            FullPath,
195            Model,
196            TimeStamp
197            )
198
199    ## InsertFile
200    #
201    # Insert one file to table
202    #
203    # @param FileFullPath:  The full path of the file
204    # @param Model:         The model of the file
205    #
206    # @retval FileID:       The ID after record is inserted
207    #
208    def InsertFile(self, File, Model):
209        return self.Insert(
210                        File.Name,
211                        File.Ext,
212                        File.Dir,
213                        File.Path,
214                        Model,
215                        File.TimeStamp
216                        )
217
218    ## Get ID of a given file
219    #
220    #   @param  FilePath    Path of file
221    #
222    #   @retval ID          ID value of given file in the table
223    #
224    def GetFileId(self, File):
225        QueryScript = "select ID from %s where FullPath = '%s'" % (self.Table, str(File))
226        RecordList = self.Exec(QueryScript)
227        if len(RecordList) == 0:
228            return None
229        return RecordList[0][0]
230
231    ## Get type of a given file
232    #
233    #   @param  FileId      ID of a file
234    #
235    #   @retval file_type   Model value of given file in the table
236    #
237    def GetFileType(self, FileId):
238        QueryScript = "select Model from %s where ID = '%s'" % (self.Table, FileId)
239        RecordList = self.Exec(QueryScript)
240        if len(RecordList) == 0:
241            return None
242        return RecordList[0][0]
243
244    ## Get file timestamp of a given file
245    #
246    #   @param  FileId      ID of file
247    #
248    #   @retval timestamp   TimeStamp value of given file in the table
249    #
250    def GetFileTimeStamp(self, FileId):
251        QueryScript = "select TimeStamp from %s where ID = '%s'" % (self.Table, FileId)
252        RecordList = self.Exec(QueryScript)
253        if len(RecordList) == 0:
254            return None
255        return RecordList[0][0]
256
257    ## Update the timestamp of a given file
258    #
259    #   @param  FileId      ID of file
260    #   @param  TimeStamp   Time stamp of file
261    #
262    def SetFileTimeStamp(self, FileId, TimeStamp):
263        self.Exec("update %s set TimeStamp=%s where ID='%s'" % (self.Table, TimeStamp, FileId))
264
265    ## Get list of file with given type
266    #
267    #   @param  FileType    Type value of file
268    #
269    #   @retval file_list   List of files with the given type
270    #
271    def GetFileList(self, FileType):
272        RecordList = self.Exec("select FullPath from %s where Model=%s" % (self.Table, FileType))
273        if len(RecordList) == 0:
274            return []
275        return [R[0] for R in RecordList]
276
277## TableDataModel
278#
279# This class defined a table used for data model
280#
281# @param object:       Inherited from object class
282#
283#
284class TableDataModel(Table):
285    _COLUMN_ = """
286        ID INTEGER PRIMARY KEY,
287        CrossIndex INTEGER NOT NULL,
288        Name VARCHAR NOT NULL,
289        Description VARCHAR
290        """
291    def __init__(self, Cursor):
292        Table.__init__(self, Cursor, 'DataModel')
293
294    ## Insert table
295    #
296    # Insert a record into table DataModel
297    #
298    # @param ID:           ID of a ModelType
299    # @param CrossIndex:   CrossIndex of a ModelType
300    # @param Name:         Name of a ModelType
301    # @param Description:  Description of a ModelType
302    #
303    def Insert(self, CrossIndex, Name, Description):
304        (Name, Description) = ConvertToSqlString((Name, Description))
305        return Table.Insert(self, CrossIndex, Name, Description)
306
307    ## Init table
308    #
309    # Create all default records of table DataModel
310    #
311    def InitTable(self):
312        EdkLogger.verbose("\nInitialize table DataModel started ...")
313        Count = self.GetCount()
314        if Count != None and Count != 0:
315            return
316        for Item in DataClass.MODEL_LIST:
317            CrossIndex = Item[1]
318            Name = Item[0]
319            Description = Item[0]
320            self.Insert(CrossIndex, Name, Description)
321        EdkLogger.verbose("Initialize table DataModel ... DONE!")
322
323    ## Get CrossIndex
324    #
325    # Get a model's cross index from its name
326    #
327    # @param ModelName:    Name of the model
328    # @retval CrossIndex:  CrossIndex of the model
329    #
330    def GetCrossIndex(self, ModelName):
331        CrossIndex = -1
332        SqlCommand = """select CrossIndex from DataModel where name = '""" + ModelName + """'"""
333        self.Cur.execute(SqlCommand)
334        for Item in self.Cur:
335            CrossIndex = Item[0]
336
337        return CrossIndex
338
339