From 0fd3ab06f9ef24f720fa5eaaaed3a42367bc5e4e Mon Sep 17 00:00:00 2001 From: JohnE Date: Thu, 11 Jun 2015 10:14:59 -0700 Subject: [PATCH] WIP: write database schema to file JSON --- libs/fingerprint.py | 53 +++++++++++++++++++++++++++++++-------------- main.py | 11 ++++++---- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/libs/fingerprint.py b/libs/fingerprint.py index 7835843..fc7385e 100644 --- a/libs/fingerprint.py +++ b/libs/fingerprint.py @@ -59,15 +59,20 @@ class DBSchema: return - def writeFingerprint(self): + def debugFingerprint(self): keys = self.tables.keys() for key in keys: print "[[ TABLE: <" + key + "> ]]" tableDef = self.tables[key] - # hehehe = tableDef.SQLstr() print str(tableDef.SQLstr()) tableDef.toJSON() - return + + + def writeFingerprint(self, filehandle): + keys = self.tables.keys() + for key in keys: + tableDef = self.tables[key] + tableDef.toFile(filehandle); def getErrorString(self, errorCode): @@ -94,8 +99,7 @@ class TableDefinition: self.tableName = "" self.sqlStr = "" self.fields = {} - # self.pkeys = [] - return + def loadTable(self, tableName, sqlStr): self.tableName = tableName @@ -104,16 +108,12 @@ class TableDefinition: if results: colstr = results.group(1) print "[[ TABLE: <" + tableName + "> ]]" - # print "FIELDS: " + colstr columns = colstr.split(',') for col in columns: newField = self.__parseCreateStr(col.strip()) if newField: self.fields[newField['name']] = newField - return - - # Table Definition # # CREATE TABLE contacts (_id INTEGER PRIMARY KEY AUTOINCREMENT,name_raw_contact_id INTEGER REFERENCES raw_contacts(_id), @@ -131,7 +131,7 @@ class TableDefinition: newField = {} # photo_id INTEGER REFERENCES data(_id) # name_raw_contact_id INTEGER REFERENCES raw_contacts(_id) - results = re.match(r'(\w+)\s+(\w+)\s+REFERENCESS\s+(\W+)', sqltext) + results = re.match(r'(?:[`|\"|\'])*(\w+)(?:[`|\"|\'])*\s+(\w+)\s+REFERENCESS\s+(\W+)', sqltext) if results: newField['name'] = results.group(1) newField['datatype'] = results.group(2) @@ -140,7 +140,16 @@ class TableDefinition: return newField # pinned INTEGER NOT NULL DEFAULT 2147483647 # send_to_voicemail INTEGER NOT NULL DEFAULT 0 - results = re.match(r'(\w+)\s+(\w+)\s+NOT NULL\s+DEFAULT\s+(\w+)', sqltext) + results = re.match(r'(?:[`|\"|\'])*(\w+)(?:[`|\"|\'])*\s+(\w+)\s+NOT NULL\s+DEFAULT\s+(\w+)', sqltext) + if results: + newField['name'] = results.group(1) + newField['datatype'] = results.group(2) + newField['notnull'] = True + newField['default'] = results.group(3) + return newField + # pinned INTEGER DEFAULT 2147483647 + # send_to_voicemail INTEGER DEFAULT 0 + results = re.match(r'(?:[`|\"|\'])*(\w+)(?:[`|\"|\'])*\s+(\w+)\s+DEFAULT\s+(\w+)', sqltext) if results: newField['name'] = results.group(1) newField['datatype'] = results.group(2) @@ -148,7 +157,15 @@ class TableDefinition: newField['default'] = results.group(3) return newField # _id INTEGER PRIMARY KEY AUTOINCREMENT - results = re.match(r'(\w+)\s+(\w+)\s+PRIMARY KEY\s+AUTOINCREMENT', sqltext) + results = re.match(r'(?:[`|\"|\'])*(\w+)(?:[`|\"|\'])*\s+(\w+)\s+PRIMARY KEY\s+AUTOINCREMENT', sqltext) + if results: + newField['name'] = results.group(1) + newField['datatype'] = results.group(2) + newField['primarykey'] = True + newField['autoincrement'] = True + return newField + # _id INTEGER PRIMARY KEY + results = re.match(r'(?:[`|\"|\'])*(\w+)(?:[`|\"|\'])*\s+(\w+)\s+PRIMARY KEY', sqltext) if results: newField['name'] = results.group(1) newField['datatype'] = results.group(2) @@ -156,26 +173,26 @@ class TableDefinition: newField['autoincrement'] = True return newField # FileID INTEGER NOT NULL - results = re.match(r'(\w+)\s+(\w+)\s+NOT NULL', sqltext) + results = re.match(r'(?:[`|\"|\'])*(\w+)(?:[`|\"|\'])*\s+(\w+)\s+NOT NULL', sqltext) if results: newField['name'] = results.group(1) newField['datatype'] = results.group(2) newField['notnull'] = True return newField # PRIMARY KEY (field_name, - results = re.match(r'PRIMARY KEY \((\w+)\,?', sqltext) + results = re.match(r'PRIMARY KEY \((?:[`|\"|\'])*(\w+)(?:[`|\"|\'])*\,?', sqltext) if results: field = self.fields[results.group(1)] field['primarykey'] = True return False # custom_ringtone TEXT - results = re.match(r'(\w+)\s+(\w+)', sqltext) + results = re.match(r'(?:[`|\"|\'])*(\w+)(?:[`|\"|\'])*\s+(\w+)', sqltext) if results: newField['name'] = results.group(1) newField['datatype'] = results.group(2) return newField # field_name) - results = re.match(r'\,?(\w+)\)', sqltext) + results = re.match(r'(?:[`|\"|\'])*(\w+)(?:[`|\"|\'])*\)', sqltext) if results: field = self.fields[results.group(1)] field['primarykey'] = True @@ -198,6 +215,10 @@ class TableDefinition: print json.dumps(self.fields) + def toFile(self, filehandle): + json.dump(self.fields, filehandle, sort_keys=True, indent=4) + + def __str__(self): global delimeter retstr = "" diff --git a/main.py b/main.py index f384c35..b5a5996 100644 --- a/main.py +++ b/main.py @@ -8,15 +8,17 @@ from libs import fingerprint def main(): - (filein, verbose) = parseArgs() + (filein, fileout, verbose) = parseArgs() #retVal = fingerprint.scanDB(filein) db = fingerprint.DBSchema() retVal = db.scanDBFile(filein) if (retVal > 0): - print "\n\n" - db.writeFingerprint() + fh = open(fileout, "w") + db.debugFingerprint() + db.writeFingerprint(fh) + fh.close() else: print db.getErrorString(retVal) @@ -31,7 +33,8 @@ def parseArgs(): args = parser.parse_args() if (args.verbose): verbose = args.verbose - return (args.file, verbose) + fileout = args.file + "_" + timestr + return (args.file, fileout, verbose) if __name__ == "__main__":