modify storage class name
Change-Id: I1727937514933e8ccf663897dca6725e3a162e9a
diff --git a/device_storage.py b/device_storage.py
new file mode 100644
index 0000000..3de7c54
--- /dev/null
+++ b/device_storage.py
@@ -0,0 +1,602 @@
+# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+#
+# Copyright (C) 2014 Regents of the University of California.
+# Author: Teng Liang <philoliang2011@gmail.com>
+# This program 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.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# A copy of the GNU General Public License is in the file COPYING.
+"""
+DeviceStorage implements a basic storage of devices and corresponding commands
+"""
+
+import os
+import sqlite3
+from pyndn import Name
+from device_profile import DeviceProfile
+from hmac_key import HMACKey
+
+INIT_DEVICE_TABLE = ["""
+CREATE TABLE IF NOT EXISTS
+ Device(
+ id INTEGER,
+ prefix BLOB NOT NULL UNIQUE,
+ location BLOB,
+ category BLOB,
+ type BLOB,
+ model BLOB,
+ serial_number BLOB,
+ manufacturer BLOB,
+ seed_name BLOB NOT NULL,
+ seed_sequence INTEGER NOT NULL,
+ seed_counter INTEGER NOT NULL,
+ seed BLOB NOT NULL,
+ configuration_token BLOB NOT NULL,
+ configuration_token_sequence INTEGER NOT NULL,
+ configuration_token_counter INTEGER NOT NULL,
+
+ PRIMARY KEY (id)
+ );
+"""]
+
+INIT_COMMAND_TABLE = ["""
+CREATE TABLE IF NOT EXISTS
+ Command(
+ id INTEGER,
+ device_id INTEGER NOT NULL,
+ name BLOB NOT NULL,
+ command_token_name BLOB NOT NULL,
+ command_token_sequence INTEGER NOT NULL,
+ command_token_counter INTEGER NOT NULL,
+ command_token BLOB NOT NULL,
+
+ PRIMARY KEY(id)
+ FOREIGN KEY(device_id) REFERENCES Device(id)
+ );
+"""]
+
+INIT_SERVICE_PROFILE_TABLE = ["""
+CREATE TABLE IF NOT EXISTS
+ ServiceProfile(
+ id INTEGER,
+ device_id INTEGER NOT NULL,
+ name BLOB NOT NULL,
+
+ PRIMARY KEY(id)
+ FOREIGN KEY(device_id) REFERENCES Device(id)
+ );
+"""]
+
+class DeviceStorage(object):
+ """
+ Create a new DeviceUserStorage to work with an SQLite file.
+ :param str databaseFilePath: (optional) The path of the SQLite file. If ommitted, use the default path.
+ """
+ def __init__(self, databaseFilePath = None):
+ if databaseFilePath == None or databaseFilePath == "":
+ if not "HOME" in os.environ:
+ home = '.'
+ else:
+ home = os.environ["HOME"]
+
+ dbDirectory = os.path.join(home, '.ndn')
+ if not os.path.exists(dbDirectory):
+ os.makedirs(dbDirectory)
+
+ databaseFilePath = os.path.join(dbDirectory, 'ndnhome-controller.db')
+
+ self._database = sqlite3.connect(databaseFilePath)
+
+ #Check if the Device table exists
+ cursor = self._database.cursor()
+ cursor.execute("SELECT name FROM sqlite_master WHERE TYPE ='table' and NAME = 'Device'")
+ if cursor.fetchone() == None:
+ #no device table exists, create one
+ for command in INIT_DEVICE_TABLE:
+ self._database.execute(command)
+ cursor.close()
+
+ #Check if the Command table exists
+ cursor = self._database.cursor()
+ cursor.execute("SELECT name FROM sqlite_master WHERE TYPE ='table' and NAME = 'Command'")
+ if cursor.fetchone() == None:
+ #no command table exists, create one
+ for command in INIT_COMMAND_TABLE:
+ self._database.execute(command)
+ cursor.close()
+
+ #Check if the ServiceProfile table exists
+ cursor = self._database.cursor()
+ cursor.execute("SELECT name FROM sqlite_master WHERE TYPE ='table' and NAME = 'ServiceProfile'")
+ if cursor.fetchone() == None:
+ #no ServiceProfile table exists, create one
+ for command in INIT_SERVICE_PROFILE_TABLE:
+ self._database.execute(command)
+ cursor.close()
+
+ self._database.commit()
+
+ def doesTableExist(self, tableName):
+ """
+ check if table exists
+ :param str tableName
+ :return True if exists, otherwise False
+ """
+ selectOperation = "SELECT name FROM sqlite_master WHERE TYPE='table' and NAME='" + tableName +"'"
+ #print selectOperation
+ cursor = self._database.cursor()
+ cursor.execute(selectOperation)
+ if cursor.fetchone() == None:
+ result = False
+ else:
+ result = True
+ cursor.close()
+ return result
+
+ def doesDeviceExist(self, prefix):
+ """
+ Check if the specified device already exists.
+
+ :param Name prefix: the prefix of device
+ :return True if the device exists, otherwise False
+ :rtype: bool
+ """
+ result = False
+ #print prefix
+ cursor = self._database.cursor()
+ cursor.execute("SELECT count(*) FROM Device WHERE prefix =?", (prefix.toUri(),))
+ (count,) = cursor.fetchone()
+ if count > 0:
+ result = True
+ #print 'device with %s is founnd, count %d' %(prefix, count)
+
+ cursor.close()
+ return result
+
+ def addDevice(self, deviceProfile, seed, configurationToken):
+ """
+ Add a new device to the Device table, do nothing if the device already exists
+
+ :param DeviceProfile devicePorfile: the deviceProfile of the device
+ :param Key seed: the seed of the device
+ :param Key configurationToken: the configurationToken of the device
+ :return the device id if it's added successfully, 0 if the device already exists, otherwise -1
+ :rtype: INTEGER
+ """
+ result = -1
+ data = (deviceProfile.getPrefix().toUri(),
+ deviceProfile.getLocation(),
+ deviceProfile.getCategory(),
+ deviceProfile.getType(),
+ deviceProfile.getModel(),
+ deviceProfile.getManufacturer(),
+ deviceProfile.getSerialNumber(),
+ seed.getName(),
+ seed.getSequence(),
+ seed.getCounter(),
+ seed.getKey(),
+ configurationToken.getKey(),
+ configurationToken.getSequence(),
+ configurationToken.getCounter()
+ )
+
+ #check if the device already exists, if yes return 0
+ prefixName = deviceProfile.getPrefix()
+ if self.doesDeviceExist(prefixName):
+ return 0
+
+ insertDevice = (
+ "INSERT INTO Device(prefix, location, category, type, model, manufacturer, serial_number, seed_name, seed_sequence, seed_counter,seed, configuration_token, configuration_token_sequence, configuration_token_counter)"
+ "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
+ )
+ cursor = self._database.cursor()
+ cursor.execute(insertDevice, data)
+ self._database.commit()
+ result = cursor.lastrowid
+ cursor.close()
+ return result
+
+ def getDeviceProfileFromDevice(self, prefix):
+ """
+ get the specified device profile
+ :param Name prefix: the device prefix
+ :return device profile of the device if exists, otherwise return None
+ :rtype: DeviceProfile
+ """
+ operation = (
+ "Select location, category, type, model, manufacturer, serial_number FROM Device "
+ "WHERE prefix = ?"
+ )
+
+ cursor = self._database.cursor()
+ cursor.execute(operation, (prefix.toUri(),))
+ result = cursor.fetchone()
+ cursor.close()
+ # print result
+ if result == None:
+ return None
+ else:
+ deviceProfile = DeviceProfile(prefix)
+ deviceProfile.setLocation(result[0])
+ deviceProfile.setCategory(result[1])
+ deviceProfile.setType(result[2])
+ deviceProfile.setModel(result[3])
+ deviceProfile.setManufacturer(result[4])
+ deviceProfile.setSerialNumber(result[5])
+
+ return deviceProfile
+
+ def getSeed(self, prefix):
+ """
+ get the seed of the specified device
+ :param Name prefix: the device prefix
+ :return seed of the device if exists, otherwise return None
+ :rtype: HMACKey
+
+ """
+ operation = (
+ "Select seed_name, seed_sequence, seed_counter, seed FROM Device "
+ "WHERE prefix = ?"
+ )
+
+ cursor = self._database.cursor()
+ cursor.execute(operation, (prefix.toUri(),))
+ result = cursor.fetchone()
+ cursor.close()
+ #print result
+ if result == None:
+ return None
+ else:
+ seed = HMACKey(result[1], result[2], result[3], result[0])
+ return seed
+
+ # raise RuntimeError("getSeed is not implemented")
+
+ def getConfigurationToken(self, prefix):
+ """
+ get the seed of the specified device
+ :param Name prefix: the device prefix
+ :return seed of the device if exists, otherwise return None
+ :rtype: HMACKey
+
+ """
+ operation = (
+ "Select configuration_token_sequence, configuration_token_counter, configuration_token FROM Device "
+ "WHERE prefix = ?"
+ )
+
+ cursor = self._database.cursor()
+ cursor.execute(operation, (prefix.toUri(),))
+ result = cursor.fetchone()
+ cursor.close()
+ #print result
+ if result == None:
+ return None
+ else:
+ configurationToken = HMACKey(result[0], result[1], result[2])
+ return configurationToken
+ # raise RuntimeError("getConfigurationToken is not implemented")
+
+ def getDeviceEntry(self, prefix):
+ """
+ get the specified device entry
+ :param Name prefix: the device prefix
+ :return '' return the corresponding row of the device
+ :rtype: str
+ """
+ cursor = self._database.cursor()
+ cursor.execute("SELECT * FROM Device WHERE prefix =?", (prefix.toUri(),))
+ row = cursor.fetchone()
+ cursor.close()
+ return row
+
+ def deleteDevice(self, prefix):
+ """
+ delete specified device.
+ :param Name prefix: The device prefix
+ :return: 1 if successful, 0 if no device to delete, otherwise -1.
+ :rtype: INTEGER
+ """
+ result = -1
+ if not self.doesDeviceExist(prefix):
+ return 0
+ cursor = self._database.cursor()
+ deleteDevice = "DELETE FROM Device WHERE prefix=?"
+ cursor.execute(deleteDevice, (prefix.toUri(),))
+ self._database.commit()
+ cursor.close()
+ return 1
+
+ def getDeviceId(self, prefix):
+ """
+ get the device id of some specified device
+ :param Name prefix: the device prefix
+ :return id of the device, 0 if the device doesn't exist
+ :rtype: INTEGER
+ """
+ if not self.doesDeviceExist(prefix):
+ return 0
+ cursor = self._database.cursor()
+ operation = "SELECT id FROM Device WHERE prefix=?"
+ cursor.execute(operation, (prefix.toUri(),))
+ result = cursor.fetchone()
+ deviceId = result[0]
+ self._database.commit()
+ cursor.close()
+ return deviceId
+
+ def updateDevice(self, prefix, newDeviceProfile = None , newSeed = None , newcConfigurationToken = None ):
+ """
+ update specifided device
+ :param Name prefix
+ :param DeviceProfile newDeviceProfile
+ :param HMACKey newSeed
+ :param newConfigurationToken
+ :return id of the device if successful, 0 if device not found, otherwise -1
+ :rtype int
+ """
+ raise RuntimeError("getConfigurationToken is not implemented")
+
+ def updateOneColumnOfDevice(self, prefix, columnName, newColumnValue):
+ """
+ update the value of a specified column of a specified device
+ :param Name prefix: the device prefix
+ :param str columnName: column to be updated
+ :param newColumnValue: new column value
+ :return id of the device if successful. 0 if device not found, otherwise -1
+ :rtype int
+ """
+ result = -1
+ if not self.doesDeviceExist(prefix):
+ return 0
+
+ updateDevice = "UPDATE Device Set " + columnName + "=? WHERE prefix=?"
+ #print updateDevice
+ cursor = self._database.cursor()
+ #print newColumnValue
+ cursor.execute(updateDevice, (newColumnValue,prefix.toUri()))
+ self._database.commit()
+ result = cursor.lastrowid
+ cursor.close()
+ return result
+
+ def doesCommandExist(self, deviceId, commandName):
+ """
+ check if the specified command already exists.
+
+ :param Integer device_id: the device id
+ :return True if the command exists, otherwise False
+ :rtype: bool
+ """
+ result = False
+
+ cursor = self._database.cursor()
+ cursor.execute("SELECT count(*) FROM Command WHERE device_id =? AND name = ?", (deviceId, commandName))
+ (count,) = cursor.fetchone()
+ if count > 0:
+ result = True
+
+ cursor.close()
+ return result
+
+ def addCommand(self, deviceId, name, commandToken):
+ """
+ Add a new command to the Command table, do nothing if the device already exists
+
+ :param int deviceId: the device id to which the command belongs to
+ :param str name: the command name
+ :param HMACKey commandToken: the command token
+ :return the command id if it's added successfully, 0 if the command already exists, otherwise -1
+ :rtype: int
+ """
+ result = -1
+ data = (deviceId,
+ name,
+ commandToken.getName(),
+ commandToken.getSequence(),
+ commandToken.getCounter(),
+ commandToken.getKey()
+ )
+
+ #check if the command already exists, if yes return 0
+ if self.doesCommandExist(deviceId, name):
+ return 0
+
+ insertCommand = (
+ "INSERT INTO Command(device_id, name, command_token_name, command_token_sequence, command_token_counter, command_token)"
+ "VALUES(?,?,?,?,?,?)"
+ )
+ cursor = self._database.cursor()
+ cursor.execute(insertCommand, data)
+ self._database.commit()
+ result = cursor.lastrowid
+ cursor.close()
+ return result
+
+ def deleteCommand(self, deviceId, name = None):
+ """
+ delete specified commands.
+ :param str name: The command name, if None, delete all commands of the device
+ :param int deviceId: device id of the command
+ :return: 1 if successful, 0 if no command to delete, otherwise -1.
+ :rtype: int
+ """
+ result = -1
+ if not name == None:
+ if not self.doesCommandExist(deviceId, name):
+ return 0
+ cursor = self._database.cursor()
+ deleteCommand = "DELETE FROM Command WHERE device_id=? AND name=?"
+ cursor.execute(deleteCommand, (deviceId, name))
+ self._database.commit()
+ cursor.close()
+ return 1
+ else:
+ selectOperation = "SELECT count(*) FROM Command WHERE deviceId=?"
+ cursor = self._database.cursor()
+ cursor.execute(selectOperation, (deviceId,))
+ (count,) = cursor.fetchone()
+ if not count > 0:
+ return 0
+ deleteCommand = "DELETE FROM Command WHERE deviceId=?"
+ cursor.execute(deleteCommand, (deviceId))
+ self._database.commit()
+ cursor.close()
+ return 1
+
+ return result
+
+ def getCommandsOfDevice(self, deviceId):
+ """
+ get all the commands of a specified device
+ :param int deviceId: device id of the command
+ :return command name list if any commands exist, otherwise None
+
+ """
+ operation = "SELECT name FROM Command WHERE device_id = ?"
+ #operation2 = "SELECT count(*) FROM Command WHERE device_id = ? "
+ cursor = self._database.cursor()
+ #cursor.execute(operation2,(deviceId,))
+ #(count,) = cursor.fetchone
+
+ #if not count > 0:
+ #return None
+ cursor.execute(operation, (deviceId,))
+ result = cursor.fetchall()
+ #print result
+ commandList = []
+ if result == None:
+ return commandList
+ else:
+ for row in result:
+ commandList.append(row[0])
+
+ return commandList
+
+ def getCommandToken(self, deviceId, commandName):
+ """
+ get command token of a specified command
+ :param int deviceId: device id of the command
+ :param str commandName: device name of the command
+ :return command token if command existsm, otherwise None
+ :rtype HMACKey
+ """
+ operation = "SELECT command_token_sequence, command_token_counter,command_token, command_token_name FROM Command WHERE device_id = ? AND name = ?"
+ cursor = self._database.cursor()
+ cursor.execute(operation, (deviceId, commandName))
+ result = cursor.fetchone()
+ if result == None:
+ return None
+ else:
+ commandToken = HMACKey(result[0], result[1], result[2], result[3])
+ return commandToken
+
+ def doesServiceProfileExist(self, deviceId, serviceProfileName):
+ """
+ check if the specified service profile already exists.
+
+ :param Integer device_id: the device id
+ :param str serviceProfileName: name of the service profile
+ :return True if the service profile exists, otherwise False
+ :rtype: bool
+ """
+ result = False
+
+ cursor = self._database.cursor()
+ cursor.execute("SELECT count(*) FROM ServiceProfile WHERE device_id =? AND name = ?", (deviceId, serviceProfileName))
+ (count,) = cursor.fetchone()
+ if count > 0:
+ result = True
+
+ cursor.close()
+ return result
+
+ def addServiceProfile(self, deviceId, name):
+ """
+ Add a new command to the ServiceProfile table, do nothing if the device already exists
+
+ :param int deviceId: the device id to which the command belongs to
+ :param str name: the service profile name
+ :return the service profile id if it's added successfully, 0 if the service profile already exists, otherwise -1
+ :rtype: int
+ """
+ result = -1
+ data = (deviceId,
+ name,
+ )
+
+ #check if the service profile already exists, if yes return 0
+ if self.doesServiceProfileExist(deviceId, name):
+ return 0
+
+ insertCommand = (
+ "INSERT INTO ServiceProfile(device_id, name)"
+ "VALUES(?,?)"
+ )
+ cursor = self._database.cursor()
+ cursor.execute(insertCommand, data)
+ self._database.commit()
+ result = cursor.lastrowid
+ cursor.close()
+ return result
+
+ def deleteServiceProfile(self, deviceId, name = None):
+ """
+ delete specified service profile.
+ :param str name: The command name, if None, delete all profiless of the device
+ :param int deviceId: device id
+ :return: 1 if successful, 0 if no service profile to delete, otherwise -1.
+ :rtype: int
+ """
+ result = -1
+ if not name == None:
+ if not self.doesServiceProfileExist(deviceId, name):
+ return 0
+ cursor = self._database.cursor()
+ deleteProfile = "DELETE FROM ServiceProfile WHERE device_id=? AND name=?"
+ cursor.execute(deleteProfile, (deviceId, name))
+ self._database.commit()
+ cursor.close()
+ return 1
+ else:
+ selectOperation = "SELECT count(*) FROM ServiceProfile WHERE deviceId=?"
+ cursor = self._database.cursor()
+ cursor.execute(selectOperation, (deviceId,))
+ (count,) = cursor.fetchone()
+ if not count > 0:
+ return 0
+ deleteProfile = "DELETE FROM ServiceProfile WHERE deviceId=?"
+ cursor.execute(deleteProfile, (deviceId))
+ self._database.commit()
+ cursor.close()
+ return 1
+
+ return result
+
+ def getServiceProfilesOfDevice(self, deviceId):
+ """
+ get all the service profiles of a specified device
+ :param int deviceId: device id of the command
+ :return service profiles name list if any service profiles exist, otherwise None
+ """
+ operation = "SELECT name FROM ServiceProfile WHERE device_id = ?"
+ cursor = self._database.cursor()
+ cursor.execute(operation, (deviceId,))
+ result = cursor.fetchall()
+ #print result
+ serviceProfileList = []
+ if not result == None:
+ for row in result:
+ serviceProfileList.append(row[0])
+ return serviceProfileList
+
+