<commit_before># Copyright 2009-2010 ITA Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Oracle Queries"""

import re

from zope.interface import classProvides
from twisted.internet import threads
from twisted.enterprise import adbapi

try:
    from lxml import etree
except ImportError:
    etree = None

try:
    import cx_Oracle
except ImportError:
    cx_Oracle = None

from nagcat import errors, log, query


class _DBColumn:
    """describes the name and type of a column, to facilitate mapping the
    attributes of a DB column into XML attribs (taken by processing
    the contents of a cx_Oracle.Cursor.description)"""

    # taken from http://cx-oracle.sourceforge.net/html/cursor.html
    CX_VAR_COLUMNS = ('name', 'type', 'display_size', 'internal_size',
                     'precision', 'scale', 'null_ok')

    def __init__(self, desc):
        """Take the decription of a cx_Oracle variable, and make it an actual
        object"""

        # these are the attributes that this item will contain
        for k,v in zip(self.CX_VAR_COLUMNS, desc):
            setattr(self, k, v)
    def __str__(self):
        return "<_DBColumn %s:%s>" % (self.name, self.type)
    def __repr__(self):
        return str(self)


class _OracleConnectionPool(adbapi.ConnectionPool):
    """a specialized connectionPool, with a modified _runQuery that fires with
    the variables of the cursor as well as the the result"""

    #! this makes me twitch, but I can't think of a better way to get the list of
    #! variables out of the otherwise inaccessible cursor
    def _runQuery(self, cursor, *args, **kwargs):
        """Override the adbpapi.ConnectionPool._runQuery, to remember and return
        the cursor, as well as the resulting data"""

        # the parent-class _runQuery() returns the result of cursor.fetchall(),
        # which might be dangerous if a rogue query were to return a huge dataset.
        result = adbapi.ConnectionPool._runQuery(self, cursor, *args, **kwargs)
        columns = map(lambda c: _DBColumn(c), cursor.description)
        return (columns, result)


class OracleSQL(query.Query):
    """Use oracle sql to execute a query against one of the databases via
    twisted's adbapi"""

    classProvides(query.IQuery)

    name = "oraclesql"

    # the field of the configuration struct that we care about
    CONF_FIELDS = ['user', 'password', 'dsn', 'sql', 'binds']

    def __init__(self, conf):
        if not etree or not cx_Oracle:
            raise errors.InitError(
                    "cx_Oracle and lxml are required for Oracle support.")

        super(OracleSQL, self).__init__(conf)
        # need to make this take a tnsname system instead of just a DBI
        for fieldname in self.CONF_FIELDS:
            if fieldname in conf:
                self.conf[fieldname] = conf.get(fieldname)

    def _start(self):
        self.dbpool = _OracleConnectionPool('cx_Oracle', user=self.conf['user'],
                                          password=self.conf['password'],
                                          dsn=self.conf['dsn'],
                                          threaded=True,
                                          cp_reconnect=True)
        log.debug("running sql %s", self.conf['sql'])
        self.deferred = self.dbpool.runQuery(self.conf['sql'],
                                             self.conf.get('binds', {}))
        self.deferred.addCallback(self._success)<commit_msg>Fix the oracle connection pool good_sql query.<commit_after># Copyright 2009-2010 ITA Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Oracle Queries"""

import re

from zope.interface import classProvides
from twisted.internet import threads
from twisted.enterprise import adbapi

try:
    from lxml import etree
except ImportError:
    etree = None

try:
    import cx_Oracle
except ImportError:
    cx_Oracle = None

from nagcat import errors, log, query


class _DBColumn:
    """describes the name and type of a column, to facilitate mapping the
    attributes of a DB column into XML attribs (taken by processing
    the contents of a cx_Oracle.Cursor.description)"""

    # taken from http://cx-oracle.sourceforge.net/html/cursor.html
    CX_VAR_COLUMNS = ('name', 'type', 'display_size', 'internal_size',
                     'precision', 'scale', 'null_ok')

    def __init__(self, desc):
        """Take the decription of a cx_Oracle variable, and make it an actual
        object"""

        # these are the attributes that this item will contain
        for k,v in zip(self.CX_VAR_COLUMNS, desc):
            setattr(self, k, v)
    def __str__(self):
        return "<_DBColumn %s:%s>" % (self.name, self.type)
    def __repr__(self):
        return str(self)


class _OracleConnectionPool(adbapi.ConnectionPool):
    """a specialized connectionPool, with a modified _runQuery that fires with
    the variables of the cursor as well as the the result"""

    #! this makes me twitch, but I can't think of a better way to get the list of
    #! variables out of the otherwise inaccessible cursor
    def _runQuery(self, cursor, *args, **kwargs):
        """Override the adbpapi.ConnectionPool._runQuery, to remember and return
        the cursor, as well as the resulting data"""

        # the parent-class _runQuery() returns the result of cursor.fetchall(),
        # which might be dangerous if a rogue query were to return a huge dataset.
        result = adbapi.ConnectionPool._runQuery(self, cursor, *args, **kwargs)
        columns = map(lambda c: _DBColumn(c), cursor.description)
        return (columns, result)


class OracleSQL(query.Query):
    """Use oracle sql to execute a query against one of the databases via
    twisted's adbapi"""

    classProvides(query.IQuery)

    name = "oraclesql"

    # the field of the configuration struct that we care about
    CONF_FIELDS = ['user', 'password', 'dsn', 'sql', 'binds']

    def __init__(self, conf):
        if not etree or not cx_Oracle:
            raise errors.InitError(
                    "cx_Oracle and lxml are required for Oracle support.")

        super(OracleSQL, self).__init__(conf)
        # need to make this take a tnsname system instead of just a DBI
        for fieldname in self.CONF_FIELDS:
            if fieldname in conf:
                self.conf[fieldname] = conf.get(fieldname)

    def _start(self):
        self.dbpool = _OracleConnectionPool('cx_Oracle', user=self.conf['user'],
                                          password=self.conf['password'],
                                          dsn=self.conf['dsn'],
                                          threaded=True,
                                          cp_good_sql='select 1 as data from dual',
                                          cp_reconnect=True)
        log.debug("running sql %s", self.conf['sql'])
        self.deferred = self.dbpool.runQuery(self.conf['sql'],
                                             self.conf.get('binds', {}))
        self.deferred.addCallback(self._success)
{'fraction_non_alphanumeric': 0.08785882937740773, 'fraction_numerical': 0.003106747856343979, 'mean_word_length': 2.5673758865248226, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2349363', 'n_tokens_mistral': 2207, 'n_tokens_neox': 2131, 'n_words': 823}