def test_1122_connection_attributes(self):
     "1122 - test connection attribute values"
     connection = oracledb.connect(test_env.get_main_user(),
                                   test_env.get_main_password(),
                                   test_env.get_connect_string(),
                                   encoding="ASCII")
     self.assertEqual(connection.maxBytesPerCharacter, 1)
     connection = oracledb.connect(test_env.get_main_user(),
                                   test_env.get_main_password(),
                                   test_env.get_connect_string(),
                                   encoding="UTF-8")
     self.assertEqual(connection.maxBytesPerCharacter, 4)
     if test_env.get_client_version() >= (12, 1):
         self.assertEqual(connection.ltxid, b'')
     self.assertEqual(connection.current_schema, None)
     connection.current_schema = "test_schema"
     self.assertEqual(connection.current_schema, "test_schema")
     self.assertEqual(connection.edition, None)
     connection.external_name = "test_external"
     self.assertEqual(connection.external_name, "test_external")
     connection.internal_name = "test_internal"
     self.assertEqual(connection.internal_name, "test_internal")
     connection.stmtcachesize = 30
     self.assertEqual(connection.stmtcachesize, 30)
     self.assertRaises(TypeError, connection.stmtcachesize, 20.5)
     self.assertRaises(TypeError, connection.stmtcachesize, "value")
 def test_2412_tagging_invalid_key(self):
     "2412 - testTagging with Invalid key"
     pool = test_env.get_pool(getmode=oracledb.SPOOL_ATTRVAL_NOWAIT)
     conn = pool.acquire()
     self.assertRaises(TypeError, pool.release, conn, tag=12345)
     if test_env.get_client_version() >= (12, 2):
         self.assertRaises(oracledb.DatabaseError, pool.release, conn,
                           tag="INVALID_TAG")
 def test_2400_pool(self):
     "2400 - test that the pool is created and has the right attributes"
     pool = test_env.get_pool(min=2, max=8, increment=3,
                              getmode=oracledb.SPOOL_ATTRVAL_WAIT)
     self.assertEqual(pool.username, test_env.get_main_user(),
                      "user name differs")
     self.assertEqual(pool.tnsentry, test_env.get_connect_string(),
                      "tnsentry differs")
     self.assertEqual(pool.dsn, test_env.get_connect_string(),
                      "dsn differs")
     self.assertEqual(pool.max, 8, "max differs")
     self.assertEqual(pool.min, 2, "min differs")
     self.assertEqual(pool.increment, 3, "increment differs")
     self.assertEqual(pool.opened, 2, "opened differs")
     self.assertEqual(pool.busy, 0, "busy not 0 at start")
     connection_1 = pool.acquire()
     self.assertEqual(pool.busy, 1, "busy not 1 after acquire")
     self.assertEqual(pool.opened, 2, "opened not unchanged (1)")
     connection_2 = pool.acquire()
     self.assertEqual(pool.busy, 2, "busy not 2 after acquire")
     self.assertEqual(pool.opened, 2, "opened not unchanged (2)")
     connection_3 = pool.acquire()
     self.assertEqual(pool.busy, 3, "busy not 3 after acquire")
     self.assertEqual(pool.opened, 5, "opened not changed (3)")
     pool.release(connection_3)
     self.assertEqual(pool.busy, 2, "busy not 2 after release")
     del connection_2
     self.assertEqual(pool.busy, 1, "busy not 1 after del")
     pool.getmode = oracledb.SPOOL_ATTRVAL_NOWAIT
     self.assertEqual(pool.getmode, oracledb.SPOOL_ATTRVAL_NOWAIT)
     if test_env.get_client_version() >= (12, 2):
         pool.getmode = oracledb.SPOOL_ATTRVAL_TIMEDWAIT
         self.assertEqual(pool.getmode, oracledb.SPOOL_ATTRVAL_TIMEDWAIT)
     pool.stmtcachesize = 50
     self.assertEqual(pool.stmtcachesize, 50)
     pool.timeout = 10
     self.assertEqual(pool.timeout, 10)
     if test_env.get_client_version() >= (12, 1):
         pool.max_lifetime_session = 10
         self.assertEqual(pool.max_lifetime_session, 10)
 def test_1123_closed_connection_attributes(self):
     "1123 - test closed connection attribute values"
     connection = test_env.get_connection()
     connection.close()
     attr_names = [
         "current_schema", "edition", "external_name", "internal_name",
         "stmtcachesize"
     ]
     if test_env.get_client_version() >= (12, 1):
         attr_names.append("ltxid")
     for name in attr_names:
         self.assertRaises(oracledb.InterfaceError, getattr, connection,
                           name)
 def test_1103_attributes(self):
     "1103 - test connection end-to-end tracing attributes"
     connection = test_env.get_connection()
     if test_env.get_client_version() >= (12, 1) \
             and not self.is_on_oracle_cloud(connection):
         sql = "select dbop_name from v$sql_monitor " \
               "where sid = sys_context('userenv', 'sid')" \
               "and status = 'EXECUTING'"
         self.__verify_attributes(connection, "dbop", "oracledb_dbop", sql)
     sql = "select sys_context('userenv', 'action') from dual"
     self.__verify_attributes(connection, "action", "oracledb_Action", sql)
     sql = "select sys_context('userenv', 'module') from dual"
     self.__verify_attributes(connection, "module", "oracledb_Module", sql)
     sql = "select sys_context('userenv', 'client_info') from dual"
     self.__verify_attributes(connection, "clientinfo", "oracledb_cinfo",
                              sql)
     sql = "select sys_context('userenv', 'client_identifier') from dual"
     self.__verify_attributes(connection, "client_identifier",
                              "oracledb_cid", sql)
    def test_2411_plsql_session_callbacks(self):
        "2411 - test PL/SQL session callbacks"
        if test_env.get_client_version() < (12, 2):
            self.skipTest("PL/SQL session callbacks not supported before 12.2")
        callback = "pkg_SessionCallback.TheCallback"
        pool = test_env.get_pool(min=2,
                                 max=8,
                                 increment=3,
                                 getmode=oracledb.SPOOL_ATTRVAL_NOWAIT,
                                 session_callback=callback)
        tags = [
            "NLS_DATE_FORMAT=SIMPLE", "NLS_DATE_FORMAT=FULL;TIME_ZONE=UTC",
            "NLS_DATE_FORMAT=FULL;TIME_ZONE=MST"
        ]
        actual_tags = [None, None, "NLS_DATE_FORMAT=FULL;TIME_ZONE=UTC"]

        # truncate PL/SQL session callback log
        conn = pool.acquire()
        cursor = conn.cursor()
        cursor.execute("truncate table PLSQLSessionCallbacks")
        conn.close()

        # request sessions with each of the first two tags
        for tag in tags[:2]:
            conn = pool.acquire(tag=tag)
            conn.close()

        # for the last tag, use the matchanytag flag
        conn = pool.acquire(tag=tags[2], matchanytag=True)
        conn.close()

        # verify the PL/SQL session callback log is accurate
        conn = pool.acquire()
        cursor = conn.cursor()
        cursor.execute("""
                select RequestedTag, ActualTag
                from PLSQLSessionCallbacks
                order by FixupTimestamp""")
        results = cursor.fetchall()
        expected_results = list(zip(tags, actual_tags))
        self.assertEqual(results, expected_results)
        conn.close()
class TestCase(test_env.BaseTestCase):

    def __test_skip(self, coll, num_to_skip, expected_content):
        filter_spec = {'$orderby': [{'path': 'name', 'order': 'desc'}]}
        doc = coll.find().filter(filter_spec).skip(num_to_skip).getOne()
        content = doc.getContent() if doc is not None else None
        self.assertEqual(content, expected_content)

    def test_3400_invalid_json(self):
        "3400 - test inserting invalid JSON value into SODA collection"
        invalid_json = "{testKey:testValue}"
        soda_db = self.connection.getSodaDatabase()
        coll = soda_db.createCollection("InvalidJSON")
        doc = soda_db.createDocument(invalid_json)
        self.assertRaises(oracledb.DatabaseError, coll.insertOne, doc)
        coll.drop()

    def test_3401_insert_documents(self):
        "3401 - test inserting documents into a SODA collection"
        soda_db = self.connection.getSodaDatabase()
        coll = soda_db.createCollection("cxoInsertDocs")
        coll.find().remove()
        values_to_insert = [
            {"name": "George", "age": 47},
            {"name": "Susan", "age": 39},
            {"name": "John", "age": 50},
            {"name": "Jill", "age": 54}
        ]
        inserted_keys = []
        for value in values_to_insert:
            doc = coll.insertOneAndGet(value)
            inserted_keys.append(doc.key)
        self.connection.commit()
        self.assertEqual(coll.find().count(), len(values_to_insert))
        for key, value in zip(inserted_keys, values_to_insert):
            doc = coll.find().key(key).getOne()
            self.assertEqual(doc.getContent(), value)
        coll.drop()

    def test_3402_skip_documents(self):
        "3402 - test skipping documents in a SODA collection"
        soda_db = self.connection.getSodaDatabase()
        coll = soda_db.createCollection("cxoSkipDocs")
        coll.find().remove()
        values_to_insert = [
            {"name": "Anna", "age": 62},
            {"name": "Mark", "age": 37},
            {"name": "Martha", "age": 43},
            {"name": "Matthew", "age": 28}
        ]
        for value in values_to_insert:
            coll.insertOne(value)
        self.connection.commit()
        self.__test_skip(coll, 0, values_to_insert[3])
        self.__test_skip(coll, 1, values_to_insert[2])
        self.__test_skip(coll, 3, values_to_insert[0])
        self.__test_skip(coll, 4, None)
        self.__test_skip(coll, 125, None)

    def test_3403_replace_document(self):
        "3403 - test replace documents in SODA collection"
        soda_db = self.connection.getSodaDatabase()
        coll = soda_db.createCollection("cxoReplaceDoc")
        coll.find().remove()
        content = {'name': 'John', 'address': {'city': 'Sydney'}}
        doc = coll.insertOneAndGet(content)
        new_content = {'name': 'John', 'address': {'city':'Melbourne'}}
        coll.find().key(doc.key).replaceOne(new_content)
        self.connection.commit()
        self.assertEqual(coll.find().key(doc.key).getOne().getContent(),
                         new_content)
        coll.drop()

    def test_3404_search_documents_with_content(self):
        "3404 - test search documents with content using $like and $regex"
        soda_db = self.connection.getSodaDatabase()
        coll = soda_db.createCollection("cxoSearchDocContent")
        coll.find().remove()
        data = [
            {'name': 'John', 'address': {'city': 'Bangalore'}},
            {'name': 'Johnson', 'address': {'city': 'Banaras'}},
            {'name': 'Joseph', 'address': {'city': 'Bangalore'}},
            {'name': 'Jibin', 'address': {'city': 'Secunderabad'}},
            {'name': 'Andrew', 'address': {'city': 'Hyderabad'}},
            {'name': 'Matthew', 'address': {'city': 'Mumbai'}}
        ]
        for value in data:
            coll.insertOne(value)
        self.connection.commit()
        filter_specs = [
            ({'name': {'$like': 'And%'}}, 1),
            ({'name': {'$like': 'J%n'}}, 3),
            ({'name': {'$like': '%hn%'}}, 2),
            ({'address.city': {'$like': 'Ban%'}}, 3),
            ({'address.city': {'$like': '%bad'}}, 2),
            ({'address.city': {'$like': 'Hyderabad'}}, 1),
            ({'address.city': {'$like': 'China%'}}, 0),
            ({'name': {'$regex': 'Jo.*'}}, 3),
            ({'name': {'$regex': '.*[ho]n'}}, 2),
            ({'name': {'$regex': 'J.*h'}}, 1),
            ({'address.city': {'$regex': 'Ba.*'}}, 3),
            ({'address.city': {'$regex': '.*bad'}}, 2),
            ({'address.city': {'$regex': 'Hyderabad'}}, 1),
            ({'name': {'$regex': 'Js.*n'}}, 0)
        ]
        for filter_spec, expected_count in filter_specs:
            self.assertEqual(coll.find().filter(filter_spec).count(),
                             expected_count, filter_spec)
        coll.drop()

    def test_3405_document_remove(self):
        "3405 - test removing documents"
        soda_db = self.connection.getSodaDatabase()
        coll = soda_db.createCollection("cxoRemoveDocs")
        coll.find().remove()
        data = [
            {'name': 'John', 'address': {'city': 'Bangalore'}},
            {'name': 'Johnson', 'address': {'city': 'Banaras'}},
            {'name': 'Joseph', 'address': {'city': 'Mangalore'}},
            {'name': 'Jibin', 'address': {'city': 'Secunderabad'}},
            {'name': 'Andrew', 'address': {'city': 'Hyderabad'}},
            {'name': 'Matthew', 'address': {'city': 'Mumbai'}}
        ]
        docs = [coll.insertOneAndGet(v) for v in data]
        coll.find().key(docs[3].key).remove()
        self.assertEqual(coll.find().count(), len(data) - 1)
        searchResults = coll.find().filter({'name': {'$like': 'Jibin'}})
        self.assertEqual(searchResults.count(), 0)
        coll.find().filter({'name': {'$like': 'John%'}}).remove()
        self.assertEqual(coll.find().count(), len(data) - 3)
        coll.find().filter({'name': {'$regex': 'J.*'}}).remove()
        self.assertEqual(coll.find().count(), len(data) - 4)
        self.connection.commit()
        coll.drop()

    def test_3406_create_and_drop_index(self):
        "3406 - test create and drop Index"
        index_name = "cxoTestIndexes_ix_1"
        index_spec =  {
            'name': index_name,
            'fields': [
                {
                    'path': 'address.city',
                    'datatype': 'string',
                    'order': 'asc'
                }
            ]
        }
        soda_db = self.connection.getSodaDatabase()
        coll = soda_db.createCollection("TestIndexes")
        coll.find().remove()
        self.connection.commit()
        coll.dropIndex(index_name)
        coll.createIndex(index_spec)
        self.assertRaises(oracledb.DatabaseError, coll.createIndex, index_spec)
        self.assertEqual(coll.dropIndex(index_name), True)
        self.assertEqual(coll.dropIndex(index_name), False)
        coll.drop()

    def test_3407_get_documents(self):
        "3407 - test getting documents from Collection"
        self.connection.autocommit = True
        soda_db = self.connection.getSodaDatabase()
        coll = soda_db.createCollection("cxoTestGetDocs")
        coll.find().remove()
        data = [
            {'name': 'John', 'address': {'city': 'Bangalore'}},
            {'name': 'Johnson', 'address': {'city': 'Banaras'}},
            {'name': 'Joseph', 'address': {'city': 'Mangalore'}},
            {'name': 'Jibin', 'address': {'city': 'Secunderabad'}},
            {'name': 'Andrew', 'address': {'city': 'Hyderabad'}}
        ]
        inserted_keys = list(sorted(coll.insertOneAndGet(v).key for v in data))
        fetched_keys = list(sorted(d.key for d in coll.find().getDocuments()))
        self.assertEqual(fetched_keys, inserted_keys)
        coll.drop()

    def test_3408_cursor(self):
        "3408 - test fetching documents from a cursor"
        self.connection.autocommit = True
        soda_db = self.connection.getSodaDatabase()
        coll = soda_db.createCollection("cxoFindViaCursor")
        coll.find().remove()
        data = [
            {'name': 'John', 'address': {'city': 'Bangalore'}},
            {'name': 'Johnson', 'address': {'city': 'Banaras'}},
            {'name': 'Joseph', 'address': {'city': 'Mangalore'}},
        ]
        inserted_keys = list(sorted(coll.insertOneAndGet(v).key for v in data))
        fetched_keys = list(sorted(d.key for d in coll.find().getCursor()))
        self.assertEqual(fetched_keys, inserted_keys)
        coll.drop()

    def test_3409_multiple_document_remove(self):
        "3409 - test removing multiple documents using multiple keys"
        soda_db = self.connection.getSodaDatabase()
        coll = soda_db.createCollection("cxoRemoveMultipleDocs")
        coll.find().remove()
        data = [
            {'name': 'John', 'address': {'city': 'Bangalore'}},
            {'name': 'Johnson', 'address': {'city': 'Banaras'}},
            {'name': 'Joseph', 'address': {'city': 'Mangalore'}},
            {'name': 'Jibin', 'address': {'city': 'Secunderabad'}},
            {'name': 'Andrew', 'address': {'city': 'Hyderabad'}},
            {'name': 'Matthew', 'address': {'city': 'Mumbai'}}
        ]
        docs = [coll.insertOneAndGet(v) for v in data]
        keys = [docs[i].key for i in (1, 3, 5)]
        num_removed = coll.find().keys(keys).remove()
        self.assertEqual(num_removed, len(keys))
        self.assertEqual(coll.find().count(), len(data) - len(keys))
        self.connection.commit()
        coll.drop()

    def test_3410_document_version(self):
        "3410 - test using version to get documents and remove them"
        soda_db = self.connection.getSodaDatabase()
        coll = soda_db.createCollection("cxoDocumentVersion")
        coll.find().remove()
        content = {'name': 'John', 'address': {'city': 'Bangalore'}}
        inserted_doc = coll.insertOneAndGet(content)
        key = inserted_doc.key
        version = inserted_doc.version
        doc = coll.find().key(key).version(version).getOne()
        self.assertEqual(doc.getContent(), content)
        new_content = {'name': 'James', 'address': {'city': 'Delhi'}}
        replacedDoc = coll.find().key(key).replaceOneAndGet(new_content)
        new_version = replacedDoc.version
        doc = coll.find().key(key).version(version).getOne()
        self.assertEqual(doc, None)
        doc = coll.find().key(key).version(new_version).getOne()
        self.assertEqual(doc.getContent(), new_content)
        self.assertEqual(coll.find().key(key).version(version).remove(), 0)
        self.assertEqual(coll.find().key(key).version(new_version).remove(), 1)
        self.assertEqual(coll.find().count(), 0)
        self.connection.commit()
        coll.drop()

    def test_3411_get_cursor(self):
        "3411 - test keys with GetCursor"
        soda_db = self.connection.getSodaDatabase()
        coll = soda_db.createCollection("cxoKeysWithGetCursor")
        coll.find().remove()
        data = [
            {'name': 'John', 'address': {'city': 'Bangalore'}},
            {'name': 'Johnson', 'address': {'city': 'Banaras'}},
            {'name': 'Joseph', 'address': {'city': 'Mangalore'}},
            {'name': 'Jibin', 'address': {'city': 'Secunderabad'}},
            {'name': 'Andrew', 'address': {'city': 'Hyderabad'}},
            {'name': 'Matthew', 'address': {'city': 'Mumbai'}}
        ]
        docs = [coll.insertOneAndGet(v) for v in data]
        keys = [docs[i].key for i in (2, 4, 5)]
        fetched_keys = [d.key for d in coll.find().keys(keys).getCursor()]
        self.assertEqual(list(sorted(fetched_keys)), list(sorted(keys)))
        self.connection.commit()
        coll.drop()

    def test_3412_created_on(self):
        "3412 - test createdOn attribute of Document"
        soda_db = self.connection.getSodaDatabase()
        coll = soda_db.createCollection("CreatedOn")
        coll.find().remove()
        data = {'name': 'John', 'address': {'city': 'Bangalore'}}
        doc = coll.insertOneAndGet(data)
        self.assertEqual(doc.createdOn, doc.lastModified)

    @unittest.skipIf(test_env.get_client_version() < (20, 1),
                     "unsupported client")
    def test_3413_soda_truncate(self):
        "3413 - test Soda truncate"
        soda_db = self.connection.getSodaDatabase()
        coll = soda_db.createCollection("cxoTruncateDocs")
        coll.find().remove()
        values_to_insert = [
            {"name": "George", "age": 47},
            {"name": "Susan", "age": 39},
            {"name": "John", "age": 50},
            {"name": "Jill", "age": 54}
        ]
        for value in values_to_insert:
            coll.insertOne(value)
        self.connection.commit()
        self.assertEqual(coll.find().count(), len(values_to_insert))
        coll.truncate()
        self.assertEqual(coll.find().count(), 0)
        coll.drop()

    @unittest.skipIf(test_env.skip_client_version_old_multi((19, 11), (21, 3)),
                     "unsupported client")
    def test_3414_soda_hint(self):
        "3414 - verify hints are reflected in the executed SQL statement"
        soda_db = self.connection.getSodaDatabase()
        cursor = self.connection.cursor()
        statement = """
                SELECT
                    ( SELECT t2.sql_fulltext
                      FROM v$sql t2
                      WHERE t2.sql_id = t1.prev_sql_id
                        AND t2.child_number = t1.prev_child_number
                    )
                 FROM v$session t1
                 WHERE t1.audsid = sys_context('userenv', 'sessionid')"""
        coll = soda_db.createCollection("cxoSodaHint")
        coll.find().remove()
        values_to_insert = [
            {"name": "George", "age": 47},
            {"name": "Susan", "age": 39},
        ]
        coll.insertOneAndGet(values_to_insert[0], hint="MONITOR")
        cursor.execute(statement)
        result, = cursor.fetchone()
        self.assertTrue('MONITOR' in result.read())

        coll.find().hint("MONITOR").getOne().getContent()
        cursor.execute(statement)
        result, = cursor.fetchone()
        self.assertTrue('MONITOR' in result.read())

        coll.insertOneAndGet(values_to_insert[1], hint="NO_MONITOR")
        cursor.execute(statement)
        result, = cursor.fetchone()
        self.assertTrue('NO_MONITOR' in result.read())
Ejemplo n.º 8
0
class TestCase(test_env.BaseTestCase):
    def _test_positive_set_and_get(self,
                                   var_type,
                                   value_to_set,
                                   expected_value,
                                   type_name=None):
        var = self.cursor.var(var_type, typename=type_name)
        var.setvalue(0, value_to_set)
        result = var.getvalue()
        if isinstance(result, oracledb.LOB):
            result = result.read()
        elif isinstance(result, oracledb.Object):
            result = self.get_db_object_as_plain_object(result)
        self.assertEqual(result, expected_value)

    def _test_negative_set_and_get(self,
                                   var_type,
                                   value_to_set,
                                   type_name=None):
        var = self.cursor.var(var_type, typename=type_name)
        self.assertRaises((TypeError, oracledb.DatabaseError), var.setvalue, 0,
                          value_to_set)

    def test_3700_DB_TYPE_NUMBER(self):
        "3700 - setting values on variables of type DB_TYPE_NUMBER"
        self._test_positive_set_and_get(oracledb.DB_TYPE_NUMBER, 5, 5)
        self._test_positive_set_and_get(oracledb.DB_TYPE_NUMBER, 3.5, 3.5)
        self._test_positive_set_and_get(oracledb.DB_TYPE_NUMBER,
                                        decimal.Decimal("24.8"), 24.8)
        self._test_positive_set_and_get(oracledb.DB_TYPE_NUMBER, True, 1)
        self._test_positive_set_and_get(oracledb.DB_TYPE_NUMBER, False, 0)
        self._test_positive_set_and_get(oracledb.DB_TYPE_NUMBER, None, None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_NUMBER, "abc")

    def test_3701_DB_TYPE_BINARY_INTEGER(self):
        "3701 - setting values on variables of type DB_TYPE_BINARY_INTEGER"
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_INTEGER, 5, 5)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_INTEGER, 3.5,
                                        3)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_INTEGER,
                                        decimal.Decimal("24.8"), 24)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_INTEGER, True,
                                        1)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_INTEGER, False,
                                        0)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_INTEGER, None,
                                        None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_BINARY_INTEGER, "abc")

    def test_3702_DB_TYPE_VARCHAR(self):
        "3702 - setting values on variables of type DB_TYPE_VARCHAR"
        value = "A VARCHAR string"
        self._test_positive_set_and_get(oracledb.DB_TYPE_VARCHAR, value, value)
        value = b"A raw string for VARCHAR"
        self._test_positive_set_and_get(oracledb.DB_TYPE_VARCHAR, value,
                                        value.decode())
        self._test_positive_set_and_get(oracledb.DB_TYPE_VARCHAR, None, None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_VARCHAR, 5)

    def test_3703_DB_TYPE_NVARCHAR(self):
        "3703 - setting values on variables of type DB_TYPE_NVARCHAR"
        value = "A NVARCHAR string"
        self._test_positive_set_and_get(oracledb.DB_TYPE_NVARCHAR, value,
                                        value)
        value = b"A raw string for NVARCHAR"
        self._test_positive_set_and_get(oracledb.DB_TYPE_NVARCHAR, value,
                                        value.decode())
        self._test_positive_set_and_get(oracledb.DB_TYPE_NVARCHAR, None, None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_NVARCHAR, 5)

    def test_3704_DB_TYPE_CHAR(self):
        "3704 - setting values on variables of type DB_TYPE_CHAR"
        value = "A CHAR string"
        self._test_positive_set_and_get(oracledb.DB_TYPE_CHAR, value, value)
        value = b"A raw string for CHAR"
        self._test_positive_set_and_get(oracledb.DB_TYPE_CHAR, value,
                                        value.decode())
        self._test_positive_set_and_get(oracledb.DB_TYPE_CHAR, None, None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_CHAR, 5)

    def test_3705_DB_TYPE_NCHAR(self):
        "3705 - setting values on variables of type DB_TYPE_NCHAR"
        value = "A NCHAR string"
        self._test_positive_set_and_get(oracledb.DB_TYPE_NCHAR, value, value)
        value = b"A raw string for NCHAR"
        self._test_positive_set_and_get(oracledb.DB_TYPE_CHAR, value,
                                        value.decode())
        self._test_positive_set_and_get(oracledb.DB_TYPE_NCHAR, None, None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_NCHAR, 5)

    def test_3706_DB_TYPE_LONG(self):
        "3706 - setting values on variables of type DB_TYPE_LONG"
        value = "Long Data" * 15000
        self._test_positive_set_and_get(oracledb.DB_TYPE_LONG, value, value)
        value = b"Raw data for LONG" * 15000
        self._test_positive_set_and_get(oracledb.DB_TYPE_LONG, value,
                                        value.decode())
        self._test_positive_set_and_get(oracledb.DB_TYPE_LONG, None, None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_LONG, 5)

    def test_3707_DB_TYPE_RAW(self):
        "3707 - setting values on variables of type DB_TYPE_RAW"
        value = b'Raw Data'
        self._test_positive_set_and_get(oracledb.DB_TYPE_RAW, value, value)
        value = "String data for RAW"
        self._test_positive_set_and_get(oracledb.DB_TYPE_RAW, value,
                                        value.encode())
        self._test_positive_set_and_get(oracledb.DB_TYPE_RAW, None, None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_RAW, 5)

    def test_3708_DB_TYPE_LONG_RAW(self):
        "3708 - setting values on variables of type DB_TYPE_LONG_RAW"
        value = b'Long Raw Data' * 15000
        self._test_positive_set_and_get(oracledb.DB_TYPE_LONG_RAW, value,
                                        value)
        value = "String data for LONG RAW" * 15000
        self._test_positive_set_and_get(oracledb.DB_TYPE_LONG_RAW, value,
                                        value.encode())
        self._test_positive_set_and_get(oracledb.DB_TYPE_LONG_RAW, None, None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_LONG_RAW, 5)

    def test_3709_DB_TYPE_DATE(self):
        "3709 - setting values on variables of type DB_TYPE_DATE"
        self._test_positive_set_and_get(oracledb.DB_TYPE_DATE,
                                        datetime.date(2017, 5, 6),
                                        datetime.datetime(2017, 5, 6))
        value = datetime.datetime(2017, 5, 6, 9, 36, 0)
        self._test_positive_set_and_get(oracledb.DB_TYPE_DATE, value, value)
        self._test_positive_set_and_get(oracledb.DB_TYPE_DATE, None, None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_DATE, 5)

    def test_3710_DB_TYPE_TIMESTAMP(self):
        "3710 - setting values on variables of type DB_TYPE_TIMESTAMP"
        self._test_positive_set_and_get(oracledb.DB_TYPE_TIMESTAMP,
                                        datetime.date(2017, 5, 6),
                                        datetime.datetime(2017, 5, 6))
        value = datetime.datetime(2017, 5, 6, 9, 36, 0, 300000)
        self._test_positive_set_and_get(oracledb.DB_TYPE_TIMESTAMP, value,
                                        value)
        self._test_positive_set_and_get(oracledb.DB_TYPE_TIMESTAMP, None, None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_TIMESTAMP, 5)

    def test_3711_DB_TYPE_TIMESTAMP_TZ(self):
        "3711 - setting values on variables of type DB_TYPE_TIMESTAMP_TZ"
        self._test_positive_set_and_get(oracledb.DB_TYPE_TIMESTAMP_TZ,
                                        datetime.date(2017, 5, 6),
                                        datetime.datetime(2017, 5, 6))
        value = datetime.datetime(2017, 5, 6, 9, 36, 0, 300000)
        self._test_positive_set_and_get(oracledb.DB_TYPE_TIMESTAMP_TZ, value,
                                        value)
        self._test_positive_set_and_get(oracledb.DB_TYPE_TIMESTAMP_TZ, None,
                                        None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_TIMESTAMP_TZ, 5)

    def test_3712_DB_TYPE_TIMESTAMP_LTZ(self):
        "3712 - setting values on variables of type DB_TYPE_TIMESTAMP_LTZ"
        self._test_positive_set_and_get(oracledb.DB_TYPE_TIMESTAMP_LTZ,
                                        datetime.date(2017, 5, 6),
                                        datetime.datetime(2017, 5, 6))
        value = datetime.datetime(2017, 5, 6, 9, 36, 0, 300000)
        self._test_positive_set_and_get(oracledb.DB_TYPE_TIMESTAMP_LTZ, value,
                                        value)
        self._test_positive_set_and_get(oracledb.DB_TYPE_TIMESTAMP_LTZ, None,
                                        None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_TIMESTAMP_LTZ, 5)

    def test_3713_DB_TYPE_BLOB(self):
        "3713 - setting values on variables of type DB_TYPE_BLOB"
        value = b'Short temp BLOB value'
        temp_blob = self.connection.createlob(oracledb.DB_TYPE_BLOB)
        temp_blob.write(value)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BLOB, temp_blob,
                                        value)
        self._test_negative_set_and_get(oracledb.DB_TYPE_CLOB, temp_blob)
        self._test_negative_set_and_get(oracledb.DB_TYPE_NCLOB, temp_blob)
        value = b'Short BLOB value'
        self._test_positive_set_and_get(oracledb.DB_TYPE_BLOB, value, value)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BLOB, None, None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_BLOB, 5)

    def test_3714_DB_TYPE_CLOB(self):
        "3714 - setting values on variables of type DB_TYPE_CLOB"
        value = 'Short temp CLOB value'
        temp_clob = self.connection.createlob(oracledb.DB_TYPE_CLOB)
        temp_clob.write(value)
        self._test_positive_set_and_get(oracledb.DB_TYPE_CLOB, temp_clob,
                                        value)
        self._test_negative_set_and_get(oracledb.DB_TYPE_BLOB, temp_clob)
        self._test_negative_set_and_get(oracledb.DB_TYPE_NCLOB, temp_clob)
        value = 'Short CLOB value'
        self._test_positive_set_and_get(oracledb.DB_TYPE_CLOB, value, value)
        self._test_positive_set_and_get(oracledb.DB_TYPE_CLOB, None, None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_CLOB, 5)

    def test_3715_DB_TYPE_NCLOB(self):
        "3715 - setting values on variables of type DB_TYPE_NCLOB"
        value = 'Short temp NCLOB value'
        temp_nclob = self.connection.createlob(oracledb.DB_TYPE_NCLOB)
        temp_nclob.write(value)
        self._test_positive_set_and_get(oracledb.DB_TYPE_NCLOB, temp_nclob,
                                        value)
        self._test_negative_set_and_get(oracledb.DB_TYPE_BLOB, temp_nclob)
        self._test_negative_set_and_get(oracledb.DB_TYPE_CLOB, temp_nclob)
        value = 'Short NCLOB Value'
        self._test_positive_set_and_get(oracledb.DB_TYPE_NCLOB, value, value)
        self._test_positive_set_and_get(oracledb.DB_TYPE_NCLOB, None, None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_NCLOB, 5)

    def test_3716_DB_TYPE_BINARY_FLOAT(self):
        "3716 - setting values on variables of type DB_TYPE_BINARY_FLOAT"
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_FLOAT, 5, 5.0)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_FLOAT, 3.5,
                                        3.5)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_FLOAT,
                                        decimal.Decimal("24.5"), 24.5)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_FLOAT, True,
                                        1.0)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_FLOAT, False,
                                        0.0)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_FLOAT, None,
                                        None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_BINARY_FLOAT, "abc")

    def test_3717_DB_TYPE_BINARY_DOUBLE(self):
        "3717 - setting values on variables of type DB_TYPE_BINARY_DOUBLE"
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_DOUBLE, 5, 5.0)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_DOUBLE, 3.5,
                                        3.5)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_DOUBLE,
                                        decimal.Decimal("192.125"), 192.125)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_DOUBLE, True,
                                        1.0)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_DOUBLE, False,
                                        0.0)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BINARY_DOUBLE, None,
                                        None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_BINARY_DOUBLE, "abc")

    def test_3718_DB_TYPE_BOOLEAN(self):
        "3718 - setting values on variables of type DB_TYPE_BOOLEAN"
        self._test_positive_set_and_get(oracledb.DB_TYPE_BOOLEAN, 5, True)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BOOLEAN, 2.0, True)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BOOLEAN, "abc", True)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BOOLEAN,
                                        decimal.Decimal("24.8"), True)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BOOLEAN, 0.0, False)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BOOLEAN, 0, False)
        self._test_positive_set_and_get(oracledb.DB_TYPE_BOOLEAN, None, None)

    def test_3719_DB_TYPE_INTERVAL_DS(self):
        "3719 - setting values on variables of type DB_TYPE_INTERVAL_DS"
        value = datetime.timedelta(days=5, seconds=56000, microseconds=123780)
        self._test_positive_set_and_get(oracledb.DB_TYPE_INTERVAL_DS, value,
                                        value)
        self._test_positive_set_and_get(oracledb.DB_TYPE_INTERVAL_DS, None,
                                        None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_INTERVAL_DS, 5)

    def test_3720_DB_TYPE_ROWID(self):
        "3720 - setting values on variables of type DB_TYPE_ROWID"
        self._test_negative_set_and_get(oracledb.DB_TYPE_ROWID, 12345)
        self._test_negative_set_and_get(oracledb.DB_TYPE_ROWID, "523lkhlf")

    def test_3721_DB_TYPE_OBJECT(self):
        "3721 - setting values on variables of type DB_TYPE_OBJECT"
        obj_type = self.connection.gettype("UDT_OBJECT")
        obj = obj_type.newobject()
        plain_obj = self.get_db_object_as_plain_object(obj)
        self._test_positive_set_and_get(oracledb.DB_TYPE_OBJECT, obj,
                                        plain_obj, "UDT_OBJECT")
        self._test_positive_set_and_get(obj_type, obj, plain_obj)
        self._test_positive_set_and_get(oracledb.DB_TYPE_OBJECT, None, None,
                                        "UDT_OBJECT")
        self._test_positive_set_and_get(obj_type, None, None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_OBJECT, "abc",
                                        "UDT_OBJECT")
        self._test_negative_set_and_get(oracledb.DB_TYPE_OBJECT, obj,
                                        "UDT_OBJECTARRAY")
        wrong_obj_type = self.connection.gettype("UDT_OBJECTARRAY")
        self._test_negative_set_and_get(wrong_obj_type, obj)

    @unittest.skipIf(test_env.get_client_version() < (21, 0),
                     "unsupported client")
    @unittest.skipIf(test_env.get_server_version() < (21, 0),
                     "unsupported server")
    def test_3722_DB_TYPE_JSON(self):
        "3722 - setting values on variables of type DB_TYPE_JSON"
        json_data = [
            5, 25.25,
            decimal.Decimal("10.25"), True, False,
            datetime.datetime(2017, 5, 6),
            datetime.datetime(2017, 5, 6, 9, 36, 0, 300000),
            datetime.timedelta(days=5, seconds=56000, microseconds=123780), {},
            'String', b'Some bytes', {
                'keyA': 1,
                'KeyB': 'Melbourne'
            }, [], [1, "A"], {
                "name": None
            }, {
                "name": "John"
            }, {
                "age": 30
            }, {
                "Permanent": True
            }, {
                "employee": {
                    "name": "John",
                    "age": 30,
                    "city": "Delhi",
                    "Parmanent": True
                }
            }, {
                "employees": ["John", "Matthew", "James"]
            }, {
                "employees": [{
                    "employee1": {
                        "name": "John",
                        "city": "Delhi"
                    }
                }, {
                    "employee2": {
                        "name": "Matthew",
                        "city": "Mumbai"
                    }
                }, {
                    "employee3": {
                        "name": "James",
                        "city": "Bangalore"
                    }
                }]
            }
        ]
        self._test_positive_set_and_get(oracledb.DB_TYPE_JSON, json_data,
                                        json_data)
        self._test_positive_set_and_get(oracledb.DB_TYPE_JSON, None, None)

    def test_3723_DB_TYPE_CURSOR(self):
        "3723 - test setting values on variables of type DB_TYPE_CURSOR"
        cursor = self.connection.cursor()
        var = self.cursor.var(oracledb.DB_TYPE_CURSOR)
        var.setvalue(0, cursor)
        self._test_positive_set_and_get(oracledb.DB_TYPE_CURSOR, None, None)
        self._test_negative_set_and_get(oracledb.DB_TYPE_CURSOR, 5)
#
# Portions Copyright 2001-2007, Computronix (Canada) Ltd., Edmonton, Alberta,
# Canada. All rights reserved.
#------------------------------------------------------------------------------
"""
3200 - Module for testing features introduced in 12.1
"""

import datetime
import unittest

import cx_Oracle as oracledb
import test_env


@unittest.skipUnless(test_env.get_client_version() >= (12, 1),
                     "unsupported client")
class TestCase(test_env.BaseTestCase):
    def test_3200_array_dml_row_counts_off(self):
        "3200 - test executing with arraydmlrowcounts mode disabled"
        self.cursor.execute("truncate table TestArrayDML")
        rows = [(1, "First"), (2, "Second")]
        sql = "insert into TestArrayDML (IntCol,StringCol) values (:1,:2)"
        self.cursor.executemany(sql, rows, arraydmlrowcounts=False)
        self.assertRaises(oracledb.DatabaseError,
                          self.cursor.getarraydmlrowcounts)
        rows = [(3, "Third"), (4, "Fourth")]
        self.cursor.executemany(sql, rows)
        self.assertRaises(oracledb.DatabaseError,
                          self.cursor.getarraydmlrowcounts)
Ejemplo n.º 10
0
class TestCase(test_env.BaseTestCase):
    requires_connection = False

    def __connect_and_drop(self):
        """Connect to the database, perform a query and drop the connection."""
        connection = test_env.get_connection(threaded=True)
        cursor = connection.cursor()
        cursor.execute("select count(*) from TestNumbers")
        count, = cursor.fetchone()
        self.assertEqual(count, 10)

    def __verify_fetched_data(self, connection):
        expected_data = [f"String {i + 1}" for i in range(10)]
        sql = "select StringCol from TestStrings order by IntCol"
        for i in range(5):
            with connection.cursor() as cursor:
                fetched_data = [s for s, in cursor.execute(sql)]
                self.assertEqual(fetched_data, expected_data)

    def __verify_args(self, connection):
        self.assertEqual(connection.username, test_env.get_main_user(),
                         "user name differs")
        self.assertEqual(connection.tnsentry, test_env.get_connect_string(),
                         "tnsentry differs")
        self.assertEqual(connection.dsn, test_env.get_connect_string(),
                         "dsn differs")

    def __verify_attributes(self, connection, attrName, value, sql):
        setattr(connection, attrName, value)
        cursor = connection.cursor()
        cursor.execute(sql)
        result, = cursor.fetchone()
        self.assertEqual(result, value, "%s value mismatch" % attrName)

    def test_1100_all_args(self):
        "1100 - connection to database with user, password, TNS separate"
        connection = test_env.get_connection()
        self.__verify_args(connection)

    def test_1101_app_context(self):
        "1101 - test use of application context"
        namespace = "CLIENTCONTEXT"
        app_context_entries = [(namespace, "ATTR1", "VALUE1"),
                               (namespace, "ATTR2", "VALUE2"),
                               (namespace, "ATTR3", "VALUE3")]
        connection = test_env.get_connection(appcontext=app_context_entries)
        cursor = connection.cursor()
        for namespace, name, value in app_context_entries:
            cursor.execute("select sys_context(:1, :2) from dual",
                           (namespace, name))
            actual_value, = cursor.fetchone()
            self.assertEqual(actual_value, value)

    def test_1102_app_context_negative(self):
        "1102 - test invalid use of application context"
        self.assertRaises(TypeError,
                          oracledb.connect,
                          user=test_env.get_main_user(),
                          password=test_env.get_main_password(),
                          dsn=test_env.get_connect_string(),
                          appcontext=[('userenv', 'action')])

    def test_1103_attributes(self):
        "1103 - test connection end-to-end tracing attributes"
        connection = test_env.get_connection()
        if test_env.get_client_version() >= (12, 1) \
                and not self.is_on_oracle_cloud(connection):
            sql = "select dbop_name from v$sql_monitor " \
                  "where sid = sys_context('userenv', 'sid')" \
                  "and status = 'EXECUTING'"
            self.__verify_attributes(connection, "dbop", "oracledb_dbop", sql)
        sql = "select sys_context('userenv', 'action') from dual"
        self.__verify_attributes(connection, "action", "oracledb_Action", sql)
        sql = "select sys_context('userenv', 'module') from dual"
        self.__verify_attributes(connection, "module", "oracledb_Module", sql)
        sql = "select sys_context('userenv', 'client_info') from dual"
        self.__verify_attributes(connection, "clientinfo", "oracledb_cinfo",
                                 sql)
        sql = "select sys_context('userenv', 'client_identifier') from dual"
        self.__verify_attributes(connection, "client_identifier",
                                 "oracledb_cid", sql)

    def test_1104_autocommit(self):
        "1104 - test use of autocommit"
        connection = test_env.get_connection()
        cursor = connection.cursor()
        other_connection = test_env.get_connection()
        other_cursor = other_connection.cursor()
        cursor.execute("truncate table TestTempTable")
        cursor.execute("insert into TestTempTable (IntCol) values (1)")
        other_cursor.execute("select IntCol from TestTempTable")
        rows = other_cursor.fetchall()
        self.assertEqual(rows, [])
        connection.autocommit = True
        cursor.execute("insert into TestTempTable (IntCol) values (2)")
        other_cursor.execute(
            "select IntCol from TestTempTable order by IntCol")
        rows = other_cursor.fetchall()
        self.assertEqual(rows, [(1, ), (2, )])

    def test_1105_bad_connect_string(self):
        "1105 - connection to database with bad connect string"
        self.assertRaises(oracledb.DatabaseError, oracledb.connect,
                          test_env.get_main_user())
        self.assertRaises(oracledb.DatabaseError, oracledb.connect,
                          test_env.get_main_user() + "@" + \
                          test_env.get_connect_string())
        self.assertRaises(oracledb.DatabaseError, oracledb.connect,
                          test_env.get_main_user() + "@" + \
                          test_env.get_connect_string() + "/" + \
                          test_env.get_main_password())

    def test_1106_bad_password(self):
        "1106 - connection to database with bad password"
        self.assertRaises(oracledb.DatabaseError,
                          oracledb.connect,
                          user=test_env.get_main_user(),
                          password=test_env.get_main_password() + "X",
                          dsn=test_env.get_connect_string())

    def test_1107_change_password(self):
        "1107 - test changing password"
        connection = test_env.get_connection()
        if self.is_on_oracle_cloud(connection):
            self.skipTest("passwords on Oracle Cloud are strictly controlled")
        sys_random = random.SystemRandom()
        new_password = "".join(sys_random.choice(string.ascii_letters) \
                       for i in range(20))
        connection.changepassword(test_env.get_main_password(), new_password)
        connection = oracledb.connect(dsn=test_env.get_connect_string(),
                                      user=test_env.get_main_user(),
                                      password=new_password)
        connection.changepassword(new_password, test_env.get_main_password())

    def test_1108_change_password_negative(self):
        "1108 - test changing password to an invalid value"
        connection = test_env.get_connection()
        if self.is_on_oracle_cloud(connection):
            self.skipTest("passwords on Oracle Cloud are strictly controlled")
        new_password = "******" * 150
        self.assertRaises(oracledb.DatabaseError, connection.changepassword,
                          test_env.get_main_password(), new_password)

    def test_1109_parse_password(self):
        "1109 - test connecting with password containing / and @ symbols"
        connection = test_env.get_connection()
        if self.is_on_oracle_cloud(connection):
            self.skipTest("passwords on Oracle Cloud are strictly controlled")
        sys_random = random.SystemRandom()
        chars = list(
            sys_random.choice(string.ascii_letters) for i in range(20))
        chars[4] = "/"
        chars[8] = "@"
        new_password = "".join(chars)
        connection.changepassword(test_env.get_main_password(), new_password)
        try:
            arg = "%s/%s@%s" % (test_env.get_main_user(), new_password,
                                test_env.get_connect_string())
            oracledb.connect(arg)
        finally:
            connection.changepassword(new_password,
                                      test_env.get_main_password())

    def test_1110_encodings(self):
        "1110 - connection with only encoding/nencoding specified should work"
        connection = oracledb.connect(test_env.get_main_user(),
                                      test_env.get_main_password(),
                                      test_env.get_connect_string())
        encoding = connection.encoding
        nencoding = connection.nencoding
        alt_encoding = "ISO-8859-1"
        connection = oracledb.connect(test_env.get_main_user(),
                                      test_env.get_main_password(),
                                      test_env.get_connect_string(),
                                      encoding=alt_encoding)
        self.assertEqual(connection.encoding, alt_encoding)
        self.assertEqual(connection.nencoding, nencoding)
        connection = oracledb.connect(test_env.get_main_user(),
                                      test_env.get_main_password(),
                                      test_env.get_connect_string(),
                                      nencoding=alt_encoding)
        self.assertEqual(connection.encoding, encoding)
        self.assertEqual(connection.nencoding, alt_encoding)

    def test_1111_different_encodings(self):
        "1111 - different encodings can be specified for encoding/nencoding"
        connection = oracledb.connect(test_env.get_main_user(),
                                      test_env.get_main_password(),
                                      test_env.get_connect_string(),
                                      encoding="UTF-8",
                                      nencoding="UTF-16")
        value = "\u03b4\u4e2a"
        cursor = connection.cursor()
        nchar_var = cursor.var(oracledb.DB_TYPE_NVARCHAR, 100)
        nchar_var.setvalue(0, value)
        cursor.execute("select :value from dual", value=nchar_var)
        result, = cursor.fetchone()
        self.assertEqual(result, value)

    def test_1112_exception_on_close(self):
        "1112 - confirm an exception is raised after closing a connection"
        connection = test_env.get_connection()
        connection.close()
        self.assertRaises(oracledb.InterfaceError, connection.rollback)

    def test_1113_connect_with_handle(self):
        "1113 - test creating a connection using a handle"
        connection = test_env.get_connection()
        cursor = connection.cursor()
        cursor.execute("truncate table TestTempTable")
        int_value = random.randint(1, 32768)
        cursor.execute("""
                insert into TestTempTable (IntCol, StringCol)
                values (:val, null)""",
                       val=int_value)
        connection2 = oracledb.connect(handle=connection.handle)
        cursor = connection2.cursor()
        cursor.execute("select IntCol from TestTempTable")
        fetched_int_value, = cursor.fetchone()
        self.assertEqual(fetched_int_value, int_value)
        cursor.close()
        self.assertRaises(oracledb.DatabaseError, connection2.close)
        connection.close()

    def test_1114_make_dsn(self):
        "1114 - test making a data source name from host, port and sid"
        format_string = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)" + \
                        "(HOST=%s)(PORT=%d))(CONNECT_DATA=(SID=%s)))"
        args = ("hostname", 1521, "TEST")
        result = oracledb.makedsn(*args)
        self.assertEqual(result, format_string % args)

    def test_1115_single_arg(self):
        "1115 - connection to database with user, password, DSN together"
        arg = "%s/%s@%s" % (test_env.get_main_user(),
                            test_env.get_main_password(),
                            test_env.get_connect_string())
        connection = oracledb.connect(arg)
        self.__verify_args(connection)

    def test_1116_version(self):
        "1116 - connection version is a string"
        connection = test_env.get_connection()
        self.assertTrue(isinstance(connection.version, str))

    def test_1117_rollback_on_close(self):
        "1117 - connection rolls back before close"
        connection = test_env.get_connection()
        cursor = connection.cursor()
        cursor.execute("truncate table TestTempTable")
        other_connection = test_env.get_connection()
        other_cursor = other_connection.cursor()
        other_cursor.execute("insert into TestTempTable (IntCol) values (1)")
        other_cursor.close()
        other_connection.close()
        cursor.execute("select count(*) from TestTempTable")
        count, = cursor.fetchone()
        self.assertEqual(count, 0)

    def test_1118_rollback_on_del(self):
        "1118 - connection rolls back before destruction"
        connection = test_env.get_connection()
        cursor = connection.cursor()
        cursor.execute("truncate table TestTempTable")
        other_connection = test_env.get_connection()
        other_cursor = other_connection.cursor()
        other_cursor.execute("insert into TestTempTable (IntCol) values (1)")
        del other_cursor
        del other_connection
        cursor.execute("select count(*) from TestTempTable")
        count, = cursor.fetchone()
        self.assertEqual(count, 0)

    def test_1119_threading(self):
        "1119 - multiple connections to database with multiple threads"
        threads = []
        for i in range(20):
            thread = threading.Thread(None, self.__connect_and_drop)
            threads.append(thread)
            thread.start()
        for thread in threads:
            thread.join()

    def test_1120_string_format(self):
        "1120 - test string format of connection"
        connection = test_env.get_connection()
        expected_value = "<cx_Oracle.Connection to %s@%s>" % \
                (test_env.get_main_user(), test_env.get_connect_string())
        self.assertEqual(str(connection), expected_value)

    def test_1121_ctx_mgr_close(self):
        "1121 - test context manager - close"
        connection = test_env.get_connection()
        with connection:
            cursor = connection.cursor()
            cursor.execute("truncate table TestTempTable")
            cursor.execute("insert into TestTempTable (IntCol) values (1)")
            connection.commit()
            cursor.execute("insert into TestTempTable (IntCol) values (2)")
        self.assertRaises(oracledb.InterfaceError, connection.ping)
        connection = test_env.get_connection()
        cursor = connection.cursor()
        cursor.execute("select count(*) from TestTempTable")
        count, = cursor.fetchone()
        self.assertEqual(count, 1)

    def test_1122_connection_attributes(self):
        "1122 - test connection attribute values"
        connection = oracledb.connect(test_env.get_main_user(),
                                      test_env.get_main_password(),
                                      test_env.get_connect_string(),
                                      encoding="ASCII")
        self.assertEqual(connection.maxBytesPerCharacter, 1)
        connection = oracledb.connect(test_env.get_main_user(),
                                      test_env.get_main_password(),
                                      test_env.get_connect_string(),
                                      encoding="UTF-8")
        self.assertEqual(connection.maxBytesPerCharacter, 4)
        if test_env.get_client_version() >= (12, 1):
            self.assertEqual(connection.ltxid, b'')
        self.assertEqual(connection.current_schema, None)
        connection.current_schema = "test_schema"
        self.assertEqual(connection.current_schema, "test_schema")
        self.assertEqual(connection.edition, None)
        connection.external_name = "test_external"
        self.assertEqual(connection.external_name, "test_external")
        connection.internal_name = "test_internal"
        self.assertEqual(connection.internal_name, "test_internal")
        connection.stmtcachesize = 30
        self.assertEqual(connection.stmtcachesize, 30)
        self.assertRaises(TypeError, connection.stmtcachesize, 20.5)
        self.assertRaises(TypeError, connection.stmtcachesize, "value")

    def test_1123_closed_connection_attributes(self):
        "1123 - test closed connection attribute values"
        connection = test_env.get_connection()
        connection.close()
        attr_names = [
            "current_schema", "edition", "external_name", "internal_name",
            "stmtcachesize"
        ]
        if test_env.get_client_version() >= (12, 1):
            attr_names.append("ltxid")
        for name in attr_names:
            self.assertRaises(oracledb.InterfaceError, getattr, connection,
                              name)

    def test_1124_ping(self):
        "1124 - test connection ping"
        connection = test_env.get_connection()
        connection.ping()

    def test_1125_transaction_begin(self):
        "1125 - test begin, prepare, cancel transaction"
        connection = test_env.get_connection()
        cursor = connection.cursor()
        cursor.execute("truncate table TestTempTable")
        connection.begin(10, 'trxnId', 'branchId')
        self.assertEqual(connection.prepare(), False)
        connection.begin(10, 'trxnId', 'branchId')
        cursor.execute("""
                insert into TestTempTable (IntCol, StringCol)
                values (1, 'tesName')""")
        self.assertEqual(connection.prepare(), True)
        connection.cancel()
        connection.rollback()
        cursor.execute("select count(*) from TestTempTable")
        count, = cursor.fetchone()
        self.assertEqual(count, 0)

    def test_1126_multiple_transactions(self):
        "1126 - test multiple transactions on the same connection"
        connection = test_env.get_connection()
        with connection.cursor() as cursor:
            cursor.execute("truncate table TestTempTable")

        id_ = random.randint(0, 2**128)
        xid = (0x1234, "%032x" % id_, "%032x" % 9)
        connection.begin(*xid)
        with connection.cursor() as cursor:
            cursor.execute("""
                    insert into TestTempTable (IntCol, StringCol)
                    values (1, 'tesName')""")
            self.assertEqual(connection.prepare(), True)
            connection.commit()

        for begin_trans in (True, False):
            val = 3
            if begin_trans:
                connection.begin()
                val = 2
            with connection.cursor() as cursor:
                cursor.execute("""
                        insert into TestTempTable (IntCol, StringCol)
                        values (:int_val, 'tesName')""",
                               int_val=val)
                connection.commit()

        expected_rows = [(1, "tesName"), (2, "tesName"), (3, "tesName")]
        with connection.cursor() as cursor:
            cursor.execute("select IntCol, StringCol from TestTempTable")
            self.assertEqual(cursor.fetchall(), expected_rows)

    def test_1127_multiple_global_transactions(self):
        "1127 - test multiple global transactions on the same connection"
        connection = test_env.get_connection()
        with connection.cursor() as cursor:
            cursor.execute("truncate table TestTempTable")

        id_ = random.randint(0, 2**128)
        xid = (0x1234, "%032x" % id_, "%032x" % 9)
        connection.begin(*xid)
        with connection.cursor() as cursor:
            cursor.execute("""
                    insert into TestTempTable (IntCol, StringCol)
                    values (1, 'tesName')""")
            self.assertEqual(connection.prepare(), True)
            connection.commit()

        for begin_trans in (True, False):
            val = 3
            if begin_trans:
                connection.begin()
                val = 2
            with connection.cursor() as cursor:
                cursor.execute("""
                        insert into TestTempTable (IntCol, StringCol)
                        values (:int_val, 'tesName')""",
                               int_val=val)
                connection.commit()

        id2_ = random.randint(0, 2**128)
        xid2 = (0x1234, "%032x" % id2_, "%032x" % 9)
        connection.begin(*xid2)
        with connection.cursor() as cursor:
            cursor.execute("""
                    insert into TestTempTable (IntCol, StringCol)
                    values (4, 'tesName')""")
            self.assertEqual(connection.prepare(), True)
            connection.commit()

        expected_rows = [(1, "tesName"), (2, "tesName"), (3, "tesName"),
                         (4, "tesName")]

        with connection.cursor() as cursor:
            cursor.execute("select IntCol, StringCol from TestTempTable")
            self.assertEqual(cursor.fetchall(), expected_rows)

    def test_1128_exception_creating_global_txn_after_local_txn(self):
        "1128 - test creating global txn after a local txn"
        connection = test_env.get_connection()
        with connection.cursor() as cursor:
            cursor.execute("truncate table TestTempTable")

        val = 2
        with connection.cursor() as cursor:
            cursor.execute("""
                    insert into TestTempTable (IntCol, StringCol)
                    values (:int_val, 'tesName')""",
                           int_val=val)

        id_ = random.randint(0, 2**128)
        xid = (0x1234, "%032x" % id_, "%032x" % 9)
        self.assertRaises(oracledb.DatabaseError, connection.begin, *xid)

    def test_1129_threading_single_connection(self):
        "1129 - single connection to database with multiple threads"
        with test_env.get_connection(threaded=True) as connection:
            threads = [
                threading.Thread(target=self.__verify_fetched_data,
                                 args=(connection, )) for i in range(3)
            ]
            for t in threads:
                t.start()
            for t in threads:
                t.join()

    def test_1130_cancel(self):
        "1130 - test connection cancel"
        conn = test_env.get_connection()

        def perform_cancel():
            time.sleep(0.1)
            conn.cancel()

        thread = threading.Thread(target=perform_cancel)
        thread.start()
        try:
            with conn.cursor() as cursor:
                self.assertRaises(oracledb.OperationalError, cursor.callproc,
                                  test_env.get_sleep_proc_name(), [2])
        finally:
            thread.join()
        with conn.cursor() as cursor:
            cursor.execute("select user from dual")
            user, = cursor.fetchone()
            self.assertEqual(user, test_env.get_main_user().upper())

    def test_1131_change_password_during_connect(self):
        "1131 - test changing password during connect"
        connection = test_env.get_connection()
        if self.is_on_oracle_cloud(connection):
            self.skipTest("passwords on Oracle Cloud are strictly controlled")
        sys_random = random.SystemRandom()
        new_password = "".join(sys_random.choice(string.ascii_letters) \
                       for i in range(20))
        connection = oracledb.connect(dsn=test_env.get_connect_string(),
                                      user=test_env.get_main_user(),
                                      password=test_env.get_main_password(),
                                      newpassword=new_password)
        connection = oracledb.connect(dsn=test_env.get_connect_string(),
                                      user=test_env.get_main_user(),
                                      password=new_password)
        connection.changepassword(new_password, test_env.get_main_password())

    def test_1132_autocommit_during_reexecute(self):
        "1132 - test use of autocommit during reexecute"
        sql = "insert into TestTempTable (IntCol, StringCol) values (:1, :2)"
        data_to_insert = [(1, "Test String #1"), (2, "Test String #2")]
        connection = test_env.get_connection()
        cursor = connection.cursor()
        other_connection = test_env.get_connection()
        other_cursor = other_connection.cursor()
        cursor.execute("truncate table TestTempTable")
        cursor.execute(sql, data_to_insert[0])
        other_cursor.execute("select IntCol, StringCol from TestTempTable")
        rows = other_cursor.fetchall()
        self.assertEqual(rows, [])
        connection.autocommit = True
        cursor.execute(sql, data_to_insert[1])
        other_cursor.execute("select IntCol, StringCol from TestTempTable")
        rows = other_cursor.fetchall()
        self.assertEqual(rows, data_to_insert)

    def test_1133_current_schema(self):
        "1133 - test current_schame is set properly"
        conn = test_env.get_connection()
        self.assertEqual(conn.current_schema, None)

        user = test_env.get_main_user().upper()
        proxy_user = test_env.get_proxy_user().upper()
        cursor = conn.cursor()
        cursor.execute(f'alter session set current_schema={proxy_user}')
        self.assertEqual(conn.current_schema, proxy_user)

        conn.current_schema = user
        self.assertEqual(conn.current_schema, user)

        cursor.execute("""
                select sys_context('userenv', 'current_schema')
                from dual""")
        result, = cursor.fetchone()
        self.assertEqual(result, user)

    def test_1134_dbms_output(self):
        "1134 - test dbms_output package"
        conn = test_env.get_connection()
        cursor = conn.cursor()
        test_string = "Testing DBMS_OUTPUT package"
        cursor.callproc("dbms_output.enable")
        cursor.execute("""
                begin
                    dbms_output.put_line(:val);
                end; """,
                       val=test_string)
        string_var = cursor.var(str)
        number_var = cursor.var(int)
        cursor.callproc("dbms_output.get_line", (string_var, number_var))
        self.assertEqual(string_var.getvalue(), test_string)

    @unittest.skipIf(test_env.get_client_version() < (18, 1),
                     "unsupported client")
    def test_1135_calltimeout(self):
        "1135 - test connection call_timeout"
        conn = test_env.get_connection()
        conn.call_timeout = 500  # milliseconds
        self.assertEqual(conn.call_timeout, 500)
        self.assertRaises(oracledb.DatabaseError,
                          conn.cursor().callproc,
                          test_env.get_sleep_proc_name(), [2])