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
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
|