Add database name insertion tool.
* Fix code formatting issues according to NFD development guidelines
* Add library interface to ndn-translator
* Minor updates to error messages
Change-Id: I5a7669885e89a34abca23653d011d608bcfe6ebf
Refs: #2694
diff --git a/tools/insert_names.py b/tools/insert_names.py
new file mode 100644
index 0000000..0122d07
--- /dev/null
+++ b/tools/insert_names.py
@@ -0,0 +1,145 @@
+#!/usr/bin/env python3
+# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+#
+# Copyright (c) 2015, Colorado State University.
+#
+# This file is part of ndn-atmos.
+#
+# ndn-atmos is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free Software
+# Foundation, either version 3 of the License, or (at your option) any later version.
+#
+# ndn-atmos is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+#
+# You should have received copies of the GNU General Public License and GNU Lesser
+# General Public License along with ndn-atmos, e.g., in COPYING.md file. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+# See AUTHORS.md for complete list of ndn-atmos authors and contributors.
+
+'''This module is for inserting NDN names in underlying database'''
+
+import mysql.connector as sql
+from mysql.connector import errorcode
+import sys
+import getpass
+import hashlib
+from ndn_cmmap_translators import atmos_translator
+
+def createTables(cursor):
+ TABLES = {}
+ TABLES['cmip5'] = (
+ "CREATE TABLE `cmip5` ("
+ " `id` int(100) AUTO_INCREMENT NOT NULL,"
+ " `sha256` varchar(64) UNIQUE NOT NULL,"
+ " `name` varchar(1000) NOT NULL,"
+ " `activity` varchar(100) NOT NULL,"
+ " `product` varchar(100) NOT NULL,"
+ " `organization` varchar(100) NOT NULL,"
+ " `model` varchar(100) NOT NULL,"
+ " `experiment` varchar(100) NOT NULL,"
+ " `frequency` varchar(100) NOT NULL,"
+ " `modeling_realm` varchar(100) NOT NULL,"
+ " `variable_name` varchar(100) NOT NULL,"
+ " `ensemble` varchar(100) NOT NULL,"
+ " `time` varchar(100) NOT NULL,"
+ " PRIMARY KEY (`id`)"
+ ") ENGINE=InnoDB")
+
+ #check if tables exist, if not create them
+ #create tables per schema in the wiki
+ for tableName, query in TABLES.items():
+ try:
+ print("Creating table {}: ".format(tableName))
+ cursor.execute(query)
+ print("Created table {}: ".format(tableName))
+ return 0
+ except sql.Error as err:
+ if err.errno == errorcode.ER_TABLE_EXISTS_ERROR:
+ print("Table already exists: %s " %(tableName))
+ return 1
+ else:
+ print("Failed to create table: %s" %(err.msg))
+ return -1
+
+def insertNames(cursor, name):
+ if __debug__:
+ print("Name to insert %s " %(name))
+
+ #hashvalue is needed since name is too long for primary key (must be <767 bytes)
+ hashValue = hashlib.sha256(str(name).encode('utf-8')).hexdigest()
+ if __debug__:
+ print("Hash of name %s " %(hashValue))
+
+ ##NOTE:must use %s to prevent sql injection in all sql queries
+ splitName = list(filter(None, name.split("/")))
+ splitName.insert(0, hashValue)
+ splitName.insert(0, name)
+ splitName = tuple(splitName)
+ if __debug__:
+ print("Name to insert in database %s" %(splitName))
+
+ addRecord = ("INSERT INTO cmip5 "
+ "(name, sha256, activity, product, organization, model, experiment, frequency,\
+ modeling_realm, variable_name, ensemble, time) "
+ "VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)")
+
+ try:
+ cursor.execute(addRecord, splitName)
+ print("Inserted record %s" %(name))
+ return 0
+ except sql.Error as err:
+ print("Error inserting name %s" %(err.msg))
+ return -1
+
+if __name__ == '__main__':
+ datafilePath = input("File/directory to translate: ")
+ configFilepath = input("Schema file path for the above file/directory: ")
+
+ #do the translation, the library should provide error messages, if any
+ ndnNames = atmos_translator.args_for_translation(datafilePath, configFilepath)
+ if len(ndnNames) == 0:
+ print("No name returned from the translator, exiting.")
+ sys.exit(-1)
+ if __debug__:
+ print("Returned NDN names: %s" %(ndnNames))
+
+ #open connection to db
+ dbName = input("Database to store NDN names?")
+ dbUsername = input("Database username?")
+ dbPasswd = getpass.getpass("Database password?")
+
+ try:
+ con = sql.connect(user=dbUsername, database=dbName, password=dbPasswd)
+ cursor = con.cursor()
+ if __debug__:
+ print("successfully connected to database")
+
+ #if tables do not exist, create tables
+ res = createTables(cursor)
+ if __debug__:
+ print("Return Code for create_tables: %s" %(res))
+
+ #if error, exit
+ if res == -1:
+ sys.exit(-1)
+
+ #if table already exists, or creation successful, continue
+ if res == 1 or res == 0:
+ for ndnName in ndnNames:
+ #get list of files and insert into database
+ res_insertNames = insertNames(cursor, ndnName)
+ if __debug__:
+ print("Return Code is %s for inserting name: %s" %(res_insertNames, ndnName))
+ con.commit()
+ except sql.Error as err:
+ if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
+ print("Incorrect username or password")
+ elif err.errno == errorcode.ER_BAD_DB_ERROR:
+ print("Database does not exist")
+ else:
+ print("Error connecting to Database: %s" %(err.msg))
+ finally:
+ con.close()