You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
4.1 KiB
Python

"""
The module that offers direct access to the Paxton Net2 database,
not using the SDK.
"""
import clr
from threading import RLock
clr.AddReference('System.Data')
from System.Data.SqlClient import SqlConnection, SqlDataAdapter, SqlCommand
from System.Data import DataSet, CommandType, ParameterDirection
from Net2Scripting.net2base import Net2Base
from Net2Scripting.pylog4net import Log4Net
class Net2DBXSException(Exception):
"""Exception class for net2 database xs
"""
pass
class DBCommand(object):
"""With wrapper for SqlCommand
"""
def __init__(self, query, con):
self._cmd = SqlCommand(query, con)
def __enter__(self):
return self._cmd
def __exit__(self, type, value, traceback):
if (self._cmd):
self._cmd.Dispose()
class Net2DBXS(Net2Base):
"""Net2 direct database access class
"""
# Class variables
_logger = Log4Net.get_logger('Net2DBXS')
_lock = RLock()
def __init__(self):
"""Class constructor
"""
self._con = None
self._connected = False
def __enter__(self):
"""With enter
"""
return self
def __exit__(self, type, value, traceback):
"""With exit
"""
self.dispose()
def _check_connect(self):
"""Check database connection
Raises Net2DBXSException if not connected.
"""
if not self._connected:
raise Net2DBXSException("Not connected to the database")
def connect(self,
user_name="sdk_user",
password="E56ABED4-2918-44F9-A110-71B61B47142A",
db='Net2',
server=None):
"""Connect to database
If the server parameter is None, named pipes are used.
For remote connections, the server parameter should contain the
windows name.
"""
self.dispose()
with Net2DBXS._lock:
if not server:
Net2DBXS._logger.Debug('Connecting through named pipes')
self._con = SqlConnection(
r"server=\\.\pipe\MSSQL$NET2\sql\query;database=%s;uid=%s;password=%s" %
(db, user_name, password))
else:
Net2DBXS._logger.Debug('Connecting over the network')
self._con = SqlConnection(
r"server=%s\NET2;database=%s;uid=%s;password=%s" %
(server, db, user_name, password))
self._con.Open()
self._connected = True
Net2DBXS._logger.Debug('Connected')
def query_db(self, query):
"""Perform database query and return data in dataset
Returns a dataset.
"""
self._check_connect()
with DBCommand(query, self._con) as cmd:
adapter = SqlDataAdapter()
adapter.SelectCommand = cmd
data = DataSet()
adapter.Fill(data)
return data
def run_stored_procedure(self, sp_name, **params):
"""Run stored procedured
Returns the stored procedure result value.
"""
with DBCommand(sp_name, self._con) as cmd:
cmd.CommandType = CommandType.StoredProcedure
# Add parameters
for name, value in params.iteritems():
cmd.Parameters.AddWithValue("@%s" % name, value)
# Add return code
cmd.Parameters.AddWithValue("@result", -1)
cmd.Parameters["@result"].Direction = ParameterDirection.ReturnValue
# Execute
cmd.ExecuteNonQuery()
return cmd.Parameters["@result"].Value
def get_all_tables(self):
"""Convenience function to retrieve all known tables / views
Returns a dataset.
"""
return self.query_db(
"select * from INFORMATION_SCHEMA.Tables order by TABLE_NAME")
def dispose(self):
"""Dispose database connection
"""
with Net2DBXS._lock:
if self._con:
try:
self._con.Close()
self._con = None
Net2DBXS._logger.Debug('Disposed')
except:
pass