database_updater::TableUpdate Class Reference

List of all members.

Public Member Functions

def __init__
def AddRow
def Apply
def CanApply
def RemoveSeqno

Public Attributes

 parent
 debug
 dbi
 is_global
 failed
 applied
 num_conv_unsign
 rows
 table_name
 start_date
 end_date
 detectormask
 simmask
 epoch
 aggregate
 task
 creation_date
 seqno

Detailed Description

A table update for a single aggregate.

Definition at line 196 of file database_updater.py.


Member Function Documentation

def database_updater::TableUpdate::__init__ (   self,
  parent,
  begin_line,
  is_global 
)

Definition at line 199 of file database_updater.py.

00199                                                   :
00200         self.parent           = parent       # Parent DatabaseUpdater
00201         self.debug            = parent.debug # Debug flag
00202         self.dbi              = parent.dbi   # Database Interface
00203         self.is_global        = is_global    # Determine local/global SEQNO
00204         self.failed           = False        # Set True if any error found while assembling update
00205         self.applied          = False        # Set True once applied.
00206         self.num_conv_unsign  = 0            # Number of unsigned integers converted
00207         self.rows             = []           # List of rows of data.
00208         self.table_name       = ""           # Table name parsed from BEGIN_TABLE line
00209         self.start_date       = ""           # Start date parsed from BEGIN_TABLE line
00210         self.end_date         = ""           # End date parsed from BEGIN_TABLE line
00211         self.detectormask     = "1"          # Hardwired, at least for now
00212         self.simmask          = "1"          # Overridden by the option SIMMASK=
00213         self.epoch            = ""           # Overridden by the option EPOCH=
00214         self.aggregate        = ""           # Aggregate number parsed from BEGIN_TABLE line
00215         self.task             = "0"          # Task number optionally parsed from BEGIN_TABLE line (default 0).
00216         self.creation_date    = ""           # Creation date parsed from BEGIN_TABLE line
00217         self.seqno            = ""           # Empty until Apply method executed.
00218         
00219         # Parse BEGIN_TABLE line
00220         mo = re.search(r"^BEGIN_TABLE\s+(\w+)\s+'(.*?)'\s+'(.*?)'\s+(\d+)\s+'(.*?)'(|\s+(.*))$",begin_line)
00221         #                 BEGIN_TABLE   TNAME   'START'   ' END '   AGGRE   'CREAT' dummy
00222         # dummy is matched to <space><options> if 1 or more options exist otherwise is the empty string 
00223         # if dummy != "" then <options> is matched to options
00224         if not mo:
00225             print "Failing update; cannot parse line: " + begin_line
00226             self.failed = True
00227             return
00228         (self.table_name,self.start_date,self.end_date,self.aggregate,self.creation_date,dummy,options) = mo.groups()
00229         if options:
00230 
00231             # Parse out {<task>} {key=value key=value ...}
00232             options = options.lower()
00233             #next two lines grab the task number if it is supplied as a lone digit 
00234             #(can be over-written by a subsequent TASK=N)
00235             mo = re.match(r"\s*(\d+)(|\s+(.*))$",options)
00236             if mo: (self.task,dummy,options) = mo.groups()
00237             while options:
00238                 mo = re.search(r"^(\S+)=(\S+)(|\s+(.*))$",options)
00239                 if not mo:
00240                     print "Failing update; cannot parse options: '%s'" % options
00241                     self.failed = True
00242                     return
00243                 (key,value,dummy,options) = mo.groups()
00244 
00245                 # Deal with TASK=
00246                 if key == "task":
00247                     print "TASK from key/value"
00248                     self.task = int(value)
00249                         
00250                 # Deal with SIMMASK=
00251                 elif key == "simmask":
00252                     if   value == "data" : self.simmask = "1"
00253                     elif value == "mc"   : self.simmask = "4"
00254                     elif value == "all"  : self.simmask = "-1"
00255                     else:
00256                         print "Failing update; bad SIMMASK option value: '%s'" % value
00257                         self.failed = True
00258                         return
00259 
00260                 # Deal with EPOCH=
00261                 elif key == "epoch":
00262                     try:
00263                         val_int = int(value)
00264                         if val_int >= 0 and val_int <= 100: self.epoch = value
00265                         else: raise
00266                     except:
00267                         print "Failing update; bad EPOCH option value: '%s'" % value
00268                         self.failed = True
00269                         return
00270                     
00271                 else:
00272                     print "Failing update; bad option key: '%s'" % key
00273                     self.failed = True
00274                     return
00275                
00276         if not self.parent.dbi.TableExists(self.table_name):
00277             print "Failing update; table %s does not exist." % self.table_name
00278             self.failed = True
00279             return
00280         for date in (self.start_date,self.end_date,self.creation_date):
00281             if not re.search(r'\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d',date):
00282                 print "Failing update; bad date '%s' in %s." % (date,begin_line)
00283                 self.failed = True
00284                 return
00285 
00286 #---------------------------------------------  TableUpdate  --------------------------------------------------
00287 
    def AddRow(self,row_line):

def database_updater::TableUpdate::AddRow (   self,
  row_line 
)
Add a row.

Definition at line 288 of file database_updater.py.

00288                              :
00289         """Add a row."""
00290 
00291         # Look for unsigned integers to convert if required.
00292         if ( not self.parent.convert_unsigned ) :
00293             self.rows.append(row_line.strip())
00294             return
00295         converted_line = ""
00296         for value in row_line.strip().split(','):
00297             try:
00298                 int_value = int(value)
00299                 if int_value > 2147483647:
00300                    int_value -= 4294967296
00301                    self.num_conv_unsign += 1
00302                    value = str(int_value)
00303             except: pass
00304             if converted_line: converted_line += ","
00305             converted_line += value
00306         self.rows.append(converted_line)
00307                 
00308 
00309 #---------------------------------------------  TableUpdate  --------------------------------------------------
00310 
    def Apply(self):

def database_updater::TableUpdate::Apply (   self  ) 
Apply update and return True if successful.
The table must already exist but it's VLD will be created if
necessary. 
If it fails it attempts to remove any data already committed.

Definition at line 311 of file database_updater.py.

00311                    :
00312         """Apply update and return True if successful.
00313         The table must already exist but it's VLD will be created if
00314         necessary. 
00315         If it fails it attempts to remove any data already committed."""
00316 
00317         if not self.CanApply(): return False
00318 
00319         # If required, create VLD table.
00320         if not self.dbi.TableExists(self.table_name + "VLD"):
00321             print "  Creating table %sVLD" % self.table_name
00322             sql = "CREATE TABLE %sVLD (" % self.table_name
00323             sql += "SEQNO integer not null primary key,"
00324             sql += "TIMESTART datetime not null,"
00325             sql += "TIMEEND datetime not null,"
00326             if self.epoch != "":
00327                 sql += "EPOCH tinyint(4),"
00328                 sql += "REALITY tinyint(4),"
00329             sql += "DETECTORMASK tinyint(4),"
00330             sql += "SIMMASK tinyint(4),"
00331             sql += "TASK integer,"
00332             sql += "AGGREGATENO integer,"
00333             sql += "CREATIONDATE datetime not null,"
00334             sql += "INSERTDATE datetime not null,"
00335             sql += "key TIMESTART (TIMESTART), "
00336             sql += "key TIMEEND (TIMEEND));"
00337             if not self.dbi.Query(sql): return False
00338 
00339         print "  Applying update to table %s for validity range '%s' - '%s' aggregate %s task %s..." %\
00340               (self.table_name,self.start_date,self.end_date,self.aggregate,self.task)
00341         if self.num_conv_unsign: print "   (%d unsigned integer converted before applying update)" % self.num_conv_unsign
00342         print "    requesting sequence number ... ",
00343         require_global = -1
00344         if self.is_global: require_global = 1
00345         cmd = 'allocate_seq_no.exe %s %d | tail -1' % (self.table_name,require_global)
00346         if self.debug: print "About to execute " + cmd
00347         inp = os.popen(cmd,"r")
00348         line = inp.readline()
00349         mo = re.search(r'(\d+)',line)
00350         if mo:  self.seqno = int(mo.group(1))
00351         if not self.seqno:
00352             print "failed to allocate a sequence number!"
00353             self.failed = True
00354             return False
00355         print "allocated sequence number %d" % self.seqno
00356 
00357         # Just to be on the safe side remove this sequence number.
00358         self.RemoveSeqno()
00359 
00360         # Process all rows adding SEQNO and ROW_COUNTER.
00361         # To improve performance a little group rows together into NUM_ROWS_PER_QUERY to reduce the
00362         # number of MySQL calls.
00363 
00364         NUM_ROWS_PER_QUERY = 100
00365         row_num = 0
00366         num_rows = len(self.rows)
00367         sql = ""
00368 
00369         while row_num < num_rows:
00370             row      = self.rows[row_num]
00371             row_num += 1
00372             if not sql: sql = "INSERT INTO %s VALUES " % self.table_name
00373             sql += "(%d, %d, %s)" % (self.seqno,row_num,row)
00374             if row_num == num_rows or row_num % NUM_ROWS_PER_QUERY == 0:
00375                 if not self.dbi.Query(sql):
00376                     print "Update has failed, attempting to remove any data."
00377                     self.RemoveSeqno()
00378                     return False
00379                 sql = ""
00380             else: sql += ","
00381 
00382         # Add VLD entry
00383 
00384         sql  = "INSERT INTO %sVLD VALUES (" % self.table_name
00385         sql += "%d, '%s', '%s'," % \
00386                (self.seqno,self.start_date,self.end_date)
00387         if self.epoch != "": sql += "%s, 0," % self.epoch
00388         sql += "'%s', '%s', %s, %s, '%s', '%s')" % \
00389                (self.detectormask,self.simmask,self.task,self.aggregate,self.creation_date,\
00390                 datetime.datetime.today().strftime("%Y-%m-%d %H:%M:%S"))
00391         if not self.dbi.Query(sql):
00392             print "Update has failed, attempting to remove any data."
00393             self.RemoveSeqno()
00394             return False
00395         
00396         self.applied = True
00397         return True
00398     
00399 #---------------------------------------------  TableUpdate  --------------------------------------------------
00400 
    def CanApply(self):

def database_updater::TableUpdate::CanApply (   self  ) 
Return True if no errors have been found processing the data,
it has not already applied and it has some rows.

Definition at line 401 of file database_updater.py.

00401                       :
00402         """Return True if no errors have been found processing the data,
00403         it has not already applied and it has some rows."""
00404         return not self.failed and not self.applied and self.rows 
00405 
00406 #---------------------------------------------  TableUpdate  --------------------------------------------------
00407 
    def RemoveSeqno(self):

def database_updater::TableUpdate::RemoveSeqno (   self  ) 
Attempt to remove sequence number.

Definition at line 408 of file database_updater.py.

00408                          :
00409         """Attempt to remove sequence number."""
00410         self.dbi.Query("DELETE FROM %s    WHERE SEQNO = %d" % (self.table_name,self.seqno))
00411         self.dbi.Query("DELETE FROM %sVLD WHERE SEQNO = %d" % (self.table_name,self.seqno))
00412         
00413 #---------------------------------------------  DatabaseUpdater  --------------------------------------------------
00414 #---------------------------------------------  DatabaseUpdater  --------------------------------------------------
00415 #---------------------------------------------  DatabaseUpdater  --------------------------------------------------
00416     
class DatabaseUpdater :


Member Data Documentation

Definition at line 214 of file database_updater.py.

Definition at line 205 of file database_updater.py.

Definition at line 216 of file database_updater.py.

Definition at line 202 of file database_updater.py.

Definition at line 201 of file database_updater.py.

Definition at line 211 of file database_updater.py.

Definition at line 210 of file database_updater.py.

Definition at line 213 of file database_updater.py.

Definition at line 204 of file database_updater.py.

Definition at line 203 of file database_updater.py.

Definition at line 206 of file database_updater.py.

Definition at line 200 of file database_updater.py.

Definition at line 207 of file database_updater.py.

Definition at line 217 of file database_updater.py.

Definition at line 212 of file database_updater.py.

Definition at line 209 of file database_updater.py.

Definition at line 208 of file database_updater.py.

Definition at line 215 of file database_updater.py.


The documentation for this class was generated from the following file:

Generated on 11 Aug 2013 for SKDatabase by  doxygen 1.6.1