susmit | 92235aa | 2015-11-05 20:24:55 -0700 | [diff] [blame^] | 1 | #!/usr/bin/env python3 |
| 2 | # -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */ |
| 3 | # |
| 4 | # Copyright (c) 2015, Colorado State University. |
| 5 | # |
| 6 | # This file is part of ndn-atmos. |
| 7 | # |
| 8 | # ndn-atmos is free software: you can redistribute it and/or modify it under the |
| 9 | # terms of the GNU Lesser General Public License as published by the Free Software |
| 10 | # Foundation, either version 3 of the License, or (at your option) any later version. |
| 11 | # |
| 12 | # ndn-atmos is distributed in the hope that it will be useful, but WITHOUT ANY |
| 13 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
| 14 | # PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. |
| 15 | # |
| 16 | # You should have received copies of the GNU General Public License and GNU Lesser |
| 17 | # General Public License along with ndn-atmos, e.g., in COPYING.md file. If not, see |
| 18 | # <http://www.gnu.org/licenses/>. |
| 19 | # |
| 20 | # See AUTHORS.md for complete list of ndn-atmos authors and contributors. |
| 21 | |
| 22 | '''This module is for inserting NDN names in underlying database''' |
| 23 | |
| 24 | import mysql.connector as sql |
| 25 | from mysql.connector import errorcode |
| 26 | import sys |
| 27 | import getpass |
| 28 | import hashlib |
| 29 | from hep_translator import hep_translator_module |
| 30 | |
| 31 | def createTables(cursor): |
| 32 | |
| 33 | #name format: <campaign>/<physics process>/<event content>/<calibration version>/<production directory>/<production file hash>.root |
| 34 | |
| 35 | TABLES = {} |
| 36 | TABLES['hep_data'] = ( |
| 37 | "CREATE TABLE `hep_data` (" |
| 38 | " `id` int(100) AUTO_INCREMENT NOT NULL," |
| 39 | " `sha256` varchar(64) UNIQUE NOT NULL," |
| 40 | " `name` varchar(1000) NOT NULL," |
| 41 | " `campaign` varchar(100) NOT NULL," |
| 42 | " `physics_process` varchar(100) NOT NULL," |
| 43 | " `event_content` varchar(100) NOT NULL," |
| 44 | " `calibration_version` varchar(100) NOT NULL," |
| 45 | " `production_dir` varchar(100) NOT NULL," |
| 46 | " `production_file_hash` varchar(100) NOT NULL," |
| 47 | " PRIMARY KEY (`id`)" |
| 48 | ") ENGINE=InnoDB") |
| 49 | |
| 50 | #check if tables exist, if not create them |
| 51 | #create tables per schema in the wiki |
| 52 | for tableName, query in TABLES.items(): |
| 53 | try: |
| 54 | print("Creating table {}: ".format(tableName)) |
| 55 | cursor.execute(query) |
| 56 | print("Created table {}: ".format(tableName)) |
| 57 | return True |
| 58 | except sql.Error as err: |
| 59 | if err.errno == errorcode.ER_TABLE_EXISTS_ERROR: |
| 60 | print("Table already exists: %s " %(tableName)) |
| 61 | return True |
| 62 | else: |
| 63 | print("Failed to create table: %s" %(err.msg)) |
| 64 | return False |
| 65 | |
| 66 | def insertName(cursor, name): |
| 67 | if __debug__: |
| 68 | print("Name to insert %s " %(name)) |
| 69 | |
| 70 | #hashvalue is needed since name is too long for primary key (must be <767 bytes) |
| 71 | hashValue = hashlib.sha256(str(name).encode('utf-8')).hexdigest() |
| 72 | if __debug__: |
| 73 | print("Hash of name %s " %(hashValue)) |
| 74 | |
| 75 | ##NOTE:must use %s to prevent sql injection in all sql queries |
| 76 | splitName = list(filter(None, name.split("/"))) |
| 77 | splitName.insert(0, hashValue) |
| 78 | splitName.insert(0, name) |
| 79 | splitName = tuple(splitName) |
| 80 | if __debug__: |
| 81 | print("Name to insert in database %s" %(splitName,)) |
| 82 | |
| 83 | addRecord = ("INSERT INTO hep_data " |
| 84 | "(name, sha256, campaign, physics_process, event_content, calibration_version, \ |
| 85 | production_dir, production_file_hash) " |
| 86 | "VALUES (%s, %s, %s, %s, %s, %s, %s, %s)") |
| 87 | |
| 88 | try: |
| 89 | cursor.execute(addRecord, splitName) |
| 90 | print("Inserted record %s" %(name)) |
| 91 | return True |
| 92 | except sql.Error as err: |
| 93 | print("Error inserting name %s, \nError:%s" %(name, err.msg)) |
| 94 | return False |
| 95 | |
| 96 | if __name__ == '__main__': |
| 97 | datafilePath = input("File/directory to translate: ") |
| 98 | configFilepath = input("Schema file path for the above file/directory: ") |
| 99 | |
| 100 | #do the translation, the library should provide error messages, if any |
| 101 | ndnNames = hep_translator_module.argsForTranslation(datafilePath, configFilepath) |
| 102 | if ndnNames is False: |
| 103 | print("Error parsing config file, exiting") |
| 104 | sys.exit(-1) |
| 105 | |
| 106 | if len(ndnNames) == 0: |
| 107 | print("No name returned from the translator, exiting.") |
| 108 | sys.exit(-1) |
| 109 | if __debug__: |
| 110 | print("Returned NDN names: %s" %(ndnNames)) |
| 111 | |
| 112 | #open connection to db |
| 113 | dbHost = input("Database Host?") |
| 114 | dbName = input("Database to store NDN names?") |
| 115 | dbUsername = input("Database username?") |
| 116 | dbPasswd = getpass.getpass("Database password?") |
| 117 | |
| 118 | try: |
| 119 | con = sql.connect(user=dbUsername, database=dbName, password=dbPasswd, host=dbHost) |
| 120 | cursor = con.cursor() |
| 121 | if __debug__: |
| 122 | print("successfully connected to database") |
| 123 | |
| 124 | #if tables do not exist, create tables |
| 125 | #if table already exists, or creation successful, continue |
| 126 | if createTables(cursor): |
| 127 | for ndnName in ndnNames: |
| 128 | #get list of files and insert into database |
| 129 | resInsertnames = insertName(cursor, ndnName[1]) |
| 130 | if __debug__: |
| 131 | print("Return Code is %s for inserting name: %s" %(resInsertnames, ndnName[1])) |
| 132 | con.commit() |
| 133 | else: |
| 134 | print("Error creating tables, exiting.") |
| 135 | |
| 136 | except sql.Error as err: |
| 137 | if err.errno == errorcode.ER_ACCESS_DENIED_ERROR: |
| 138 | print("Incorrect username or password") |
| 139 | elif err.errno == errorcode.ER_BAD_DB_ERROR: |
| 140 | print("Database does not exist") |
| 141 | else: |
| 142 | print("Error connecting to Database: %s" %(err.msg)) |
| 143 | finally: |
| 144 | con.close() |