def test_adapt_bytes(self):
     snowman = u"\u2603"
     self.conn.set_client_encoding('utf8')
     a = psycopg2.extensions.QuotedString(snowman.encode('utf8'))
     a.prepare(self.conn)
     q = a.getquoted()
     self.assert_(q in (b("'\xe2\x98\x83'"), b("E'\xe2\x98\x83'")), q)
示例#2
0
    def getquoted(self):
        if self.name is None:
            raise NotImplementedError(
                'RangeAdapter must be subclassed overriding its name '
                'or the getquoted() method')

        r = self.adapted
        if r.isempty:
            return b("'empty'::" + self.name)

        if r.lower is not None:
            a = adapt(r.lower)
            if hasattr(a, 'prepare'):
                a.prepare(self._conn)
            lower = a.getquoted()
        else:
            lower = b'NULL'

        if r.upper is not None:
            a = adapt(r.upper)
            if hasattr(a, 'prepare'):
                a.prepare(self._conn)
            upper = a.getquoted()
        else:
            upper = b'NULL'

        return b(self.name + '(') + lower + b', ' + upper \
                + b(", '%s')" % r._bounds)
示例#3
0
    def test_mogrify_unicode(self):
        conn = self.conn
        cur = conn.cursor()

        # test consistency between execute and mogrify.

        # unicode query containing only ascii data
        cur.execute(u"SELECT 'foo';")
        self.assertEqual('foo', cur.fetchone()[0])
        self.assertEqual(b("SELECT 'foo';"), cur.mogrify(u"SELECT 'foo';"))

        conn.set_client_encoding('UTF8')
        snowman = u"\u2603"

        # unicode query with non-ascii data
        cur.execute(u"SELECT '%s';" % snowman)
        self.assertEqual(snowman.encode('utf8'), b(cur.fetchone()[0]))
        self.assertEqual(("SELECT '%s';" % snowman).encode('utf8'),
            cur.mogrify(u"SELECT '%s';" % snowman).replace(b("E'"), b("'")))

        # unicode args
        cur.execute("SELECT %s;", (snowman,))
        self.assertEqual(snowman.encode("utf-8"), b(cur.fetchone()[0]))
        self.assertEqual(("SELECT '%s';" % snowman).encode('utf8'),
            cur.mogrify("SELECT %s;", (snowman,)).replace(b("E'"), b("'")))

        # unicode query and args
        cur.execute(u"SELECT %s;", (snowman,))
        self.assertEqual(snowman.encode("utf-8"), b(cur.fetchone()[0]))
        self.assertEqual(("SELECT '%s';" % snowman).encode('utf8'),
            cur.mogrify(u"SELECT %s;", (snowman,)).replace(b("E'"), b("'")))
示例#4
0
    def _getquoted_9(self):
        """Use the hstore(text[], text[]) function."""
        if not self.wrapped:
            return b("''::hstore")

        k = _ext.adapt(self.wrapped.keys())
        k.prepare(self.conn)
        v = _ext.adapt(self.wrapped.values())
        v.prepare(self.conn)
        return b("hstore(") + k.getquoted() + b(", ") + v.getquoted() + b(")")
    def test_read_binary(self):
        lo = self.conn.lobject()
        length = lo.write(b("some data"))
        lo.close()

        lo = self.conn.lobject(lo.oid, "rb")
        x = lo.read(4)
        self.assertEqual(type(x), type(b('')))
        self.assertEqual(x, b("some"))
        self.assertEqual(lo.read(), b(" data"))
示例#6
0
def adapt_range(pgrange, pyrange):
    if not isinstance(pyrange, range_):
        raise ValueError((
            "Trying to adapt range {range.__class__.__name__} which does not "
            "extend base range type.").format(range=pyrange))

    if not pyrange:
        return AsIs("'empty'::" + pgrange)

    lower = b("NULL")
    if not pyrange.lower_inf:
        lower = adapt(pyrange.lower).getquoted()

    upper = b("NULL")
    if not pyrange.upper_inf:
        upper = adapt(pyrange.upper).getquoted()

    return AsIs(b"".join([
        b(pgrange),
        b("("),
        lower,
        b(", "),
        upper,
        b(", '"),
        b("[" if pyrange.lower_inc else "("),
        b("]" if pyrange.upper_inc else ")"),
        b("')")
    ]).decode("utf8"))
 def test_set_encoding(self):
     # Note: this works-ish mostly in case when the standard db connection
     # we test with is utf8, otherwise the encoding chosen by PQescapeString
     # may give bad results.
     from psycopg2.extensions import adapt
     snowman = u"\u2603"
     a = adapt(snowman)
     a.encoding = 'utf8'
     self.assertEqual(a.encoding, 'utf8')
     q = a.getquoted()
     self.assert_(q in (b("'\xe2\x98\x83'"), b("E'\xe2\x98\x83'")), q)
    def test_connection_wins_anyway(self):
        from psycopg2.extensions import adapt
        snowman = u"\u2603"
        a = adapt(snowman)
        a.encoding = 'latin9'

        self.conn.set_client_encoding('utf8')
        a.prepare(self.conn)

        self.assertEqual(a.encoding, 'utf_8')
        q = a.getquoted()
        self.assert_(q in (b("'\xe2\x98\x83'"), b("E'\xe2\x98\x83'")), q)
    def test_inet_conform(self):
        from psycopg2.extras import Inet

        i = Inet("192.168.1.0/24")
        a = psycopg2.extensions.adapt(i)
        a.prepare(self.conn)
        self.assertEqual(filter_scs(self.conn, b("E'192.168.1.0/24'::inet")), a.getquoted())

        # adapts ok with unicode too
        i = Inet(u"192.168.1.0/24")
        a = psycopg2.extensions.adapt(i)
        a.prepare(self.conn)
        self.assertEqual(filter_scs(self.conn, b("E'192.168.1.0/24'::inet")), a.getquoted())
    def test_export(self):
        lo = self.conn.lobject()
        lo.write(b("some data"))

        self.tmpdir = tempfile.mkdtemp()
        filename = os.path.join(self.tmpdir, "data.txt")
        lo.export(filename)
        self.assertTrue(os.path.exists(filename))
        f = open(filename, "rb")
        try:
            self.assertEqual(f.read(), b("some data"))
        finally:
            f.close()
 def test_none_in_record(self):
     curs = self.conn.cursor()
     s = curs.mogrify("SELECT %s;", [(42, None)])
     self.assertEqual(b("SELECT (42, NULL);"), s)
     curs.execute("SELECT %s;", [(42, None)])
     d = curs.fetchone()[0]
     self.assertEqual("(42,)", d)
示例#12
0
 def test_full_escaped_octal(self):
     buf = ''.join(("\\%03o" % i) for i in range(256))
     rv = self.cast(b(buf))
     if sys.version_info[0] < 3:
         self.assertEqual(rv, ''.join(map(chr, list(range(256)))))
     else:
         self.assertEqual(rv, bytes(list(range(256))))
    def test_adapt_8(self):
        if self.conn.server_version >= 90000:
            return self.skipTest("skipping dict adaptation with PG pre-9 syntax")

        from psycopg2.extras import HstoreAdapter

        o = {"a": "1", "b": "'", "c": None}
        if self.conn.encoding == "UTF8":
            o["d"] = u"\xe0"

        a = HstoreAdapter(o)
        a.prepare(self.conn)
        q = a.getquoted()

        self.assert_(q.startswith(b("((")), q)
        ii = q[1:-1].split(b("||"))
        ii.sort()

        self.assertEqual(len(ii), len(o))
        self.assertEqual(ii[0], filter_scs(self.conn, b("(E'a' => E'1')")))
        self.assertEqual(ii[1], filter_scs(self.conn, b("(E'b' => E'''')")))
        self.assertEqual(ii[2], filter_scs(self.conn, b("(E'c' => NULL)")))
        if "d" in o:
            encc = u"\xe0".encode(psycopg2.extensions.encodings[self.conn.encoding])
            self.assertEqual(ii[3], filter_scs(self.conn, b("(E'd' => E'") + encc + b("')")))
    def test_import(self):
        self.tmpdir = tempfile.mkdtemp()
        filename = os.path.join(self.tmpdir, "data.txt")
        fp = open(filename, "wb")
        fp.write(b("some data"))
        fp.close()

        lo = self.conn.lobject(0, "r", 0, filename)
        self.assertEqual(lo.read(), "some data")
示例#15
0
 def test_full_hex(self, upper=False):
     buf = ''.join(("%02x" % i) for i in range(256))
     if upper: buf = buf.upper()
     buf = '\\x' + buf
     rv = self.cast(b(buf))
     if sys.version_info[0] < 3:
         self.assertEqual(rv, ''.join(map(chr, list(range(256)))))
     else:
         self.assertEqual(rv, bytes(list(range(256))))
    def test_read(self):
        lo = self.conn.lobject()
        length = lo.write(b("some data"))
        lo.close()

        lo = self.conn.lobject(lo.oid)
        x = lo.read(4)
        self.assertEqual(type(x), type(''))
        self.assertEqual(x, "some")
        self.assertEqual(lo.read(), " data")
示例#17
0
    def test_mogrify_decimal_explodes(self):
        # issue #7: explodes on windows with python 2.5 and psycopg 2.2.2
        try:
            from decimal import Decimal
        except:
            return

        conn = self.conn
        cur = conn.cursor()
        self.assertEqual(b("SELECT 10.3;"), cur.mogrify("SELECT %s;", (Decimal("10.3"),)))
示例#18
0
    def test_adapt_subtype_3(self):
        from psycopg2.extensions import adapt, register_adapter, AsIs

        class A: pass
        class B(A): pass

        register_adapter(A, lambda a: AsIs("a"))
        try:
            self.assertEqual(b("a"), adapt(B()).getquoted())
        finally:
           del psycopg2.extensions.adapters[A, psycopg2.extensions.ISQLQuote]
示例#19
0
    def getquoted(self):
        if self.name is None:
            raise NotImplementedError(
                "RangeAdapter must be subclassed overriding its name " "or the getquoted() method"
            )

        r = self.adapted
        if r.isempty:
            return b("'empty'::" + self.name)

        if r.lower is not None:
            a = adapt(r.lower)
            if hasattr(a, "prepare"):
                a.prepare(self._conn)
            lower = a.getquoted()
        else:
            lower = b("NULL")

        if r.upper is not None:
            a = adapt(r.upper)
            if hasattr(a, "prepare"):
                a.prepare(self._conn)
            upper = a.getquoted()
        else:
            upper = b("NULL")

        return b(self.name + "(") + lower + b(", ") + upper + b(", '%s')" % r._bounds)
示例#20
0
    def test_binary(self):
        data = b("""some data with \000\013 binary
        stuff into, 'quotes' and \\ a backslash too.
        """)
        if sys.version_info[0] < 3:
            data += "".join(map(chr, range(256)))
        else:
            data += bytes(range(256))

        curs = self.conn.cursor()
        curs.execute("SELECT %s::bytea;", (psycopg2.Binary(data),))
        if sys.version_info[0] < 3:
            res = str(curs.fetchone()[0])
        else:
            res = curs.fetchone()[0].tobytes()

        if res[0] in (b('x'), ord(b('x'))) and self.conn.server_version >= 90000:
            return self.skipTest(
                "bytea broken with server >= 9.0, libpq < 9")

        self.assertEqual(res, data)
        self.assert_(not self.conn.notices)
    def test_truncate(self):
        lo = self.conn.lobject()
        lo.write(b("some data"))
        lo.close()

        lo = self.conn.lobject(lo.oid, "w")
        lo.truncate(4)

        # seek position unchanged
        self.assertEqual(lo.tell(), 0)
        # data truncated
        self.assertEqual(lo.read(), b("some"))

        lo.truncate(6)
        lo.seek(0)
        # large object extended with zeroes
        self.assertEqual(lo.read(), b("some\x00\x00"))

        lo.truncate()
        lo.seek(0)
        # large object empty
        self.assertEqual(lo.read(), b(""))
示例#22
0
    def test_adapt_most_specific(self):
        from psycopg2.extensions import adapt, register_adapter, AsIs

        class A(object): pass
        class B(A): pass
        class C(B): pass

        register_adapter(A, lambda a: AsIs("a"))
        register_adapter(B, lambda b: AsIs("b"))
        try:
            self.assertEqual(b('b'), adapt(C()).getquoted())
        finally:
           del psycopg2.extensions.adapters[A, psycopg2.extensions.ISQLQuote]
           del psycopg2.extensions.adapters[B, psycopg2.extensions.ISQLQuote]
示例#23
0
    def test_escaped_mixed(self):
        import string

        buf = "".join(("\\%03o" % i) for i in range(32))
        buf += string.ascii_letters
        buf += "".join("\\" + c for c in string.ascii_letters)
        buf += "\\\\"
        rv = self.cast(b(buf))
        if sys.version_info[0] < 3:
            tgt = "".join(map(chr, range(32))) + string.ascii_letters * 2 + "\\"
        else:
            tgt = bytes(range(32)) + (string.ascii_letters * 2 + "\\").encode("ascii")

        self.assertEqual(rv, tgt)
示例#24
0
    def test_escaped_mixed(self):
        import string
        buf = ''.join(("\\%03o" % i) for i in range(32))
        buf += string.ascii_letters
        buf += ''.join('\\' + c for c in string.ascii_letters)
        buf += '\\\\'
        rv = self.cast(b(buf))
        if sys.version_info[0] < 3:
            tgt = ''.join(map(chr, list(range(32)))) \
                + string.ascii_letters * 2 + '\\'
        else:
            tgt = bytes(list(range(32))) + \
                (string.ascii_letters * 2 + '\\').encode('ascii')

        self.assertEqual(rv, tgt)
示例#25
0
    def test_adapt_most_specific(self):
        from psycopg2.extensions import adapt, register_adapter, AsIs

        class A(object):
            pass

        class B(A):
            pass

        class C(B):
            pass

        register_adapter(A, lambda a: AsIs("a"))
        register_adapter(B, lambda b: AsIs("b"))
        try:
            self.assertEqual(b('b'), adapt(C()).getquoted())
        finally:
            del psycopg2.extensions.adapters[A, psycopg2.extensions.ISQLQuote]
            del psycopg2.extensions.adapters[B, psycopg2.extensions.ISQLQuote]
    def test_seek_tell(self):
        lo = self.conn.lobject()
        length = lo.write(b("some data"))
        self.assertEqual(lo.tell(), length)
        lo.close()
        lo = self.conn.lobject(lo.oid)

        self.assertEqual(lo.seek(5, 0), 5)
        self.assertEqual(lo.tell(), 5)
        self.assertEqual(lo.read(), "data")

        # SEEK_CUR: relative current location
        lo.seek(5)
        self.assertEqual(lo.seek(2, 1), 7)
        self.assertEqual(lo.tell(), 7)
        self.assertEqual(lo.read(), "ta")

        # SEEK_END: relative to end of file
        self.assertEqual(lo.seek(-2, 2), length - 2)
        self.assertEqual(lo.read(), "ta")
示例#27
0
    def test_none_fast_path(self):
        # the None adapter is not actually invoked in regular adaptation
        ext = psycopg2.extensions

        class WonkyAdapter(object):
            def __init__(self, obj): pass
            def getquoted(self): return "NOPE!"

        curs = self.conn.cursor()

        orig_adapter = ext.adapters[type(None), ext.ISQLQuote]
        try:
            ext.register_adapter(type(None), WonkyAdapter)
            self.assertEqual(ext.adapt(None).getquoted(), "NOPE!")

            s = curs.mogrify("SELECT %s;", (None,))
            self.assertEqual(b("SELECT NULL;"), s)

        finally:
            ext.register_adapter(type(None), orig_adapter)
示例#28
0
    def test_none_fast_path(self):
        # the None adapter is not actually invoked in regular adaptation
        ext = psycopg2.extensions

        class WonkyAdapter(object):
            def __init__(self, obj): pass
            def getquoted(self): return "NOPE!"

        curs = self.conn.cursor()

        orig_adapter = ext.adapters[type(None), ext.ISQLQuote]
        try:
            ext.register_adapter(type(None), WonkyAdapter)
            self.assertEqual(ext.adapt(None).getquoted(), "NOPE!")

            s = curs.mogrify("SELECT %s;", (None,))
            self.assertEqual(b("SELECT NULL;"), s)

        finally:
            ext.register_adapter(type(None), orig_adapter)
示例#29
0
    def getquoted(self):
        r = self.adapted
        if r.isempty:
            return b("'empty'")

        if not r.lower_inf:
            # not exactly: we are relying that none of these object is really
            # quoted (they are numbers). Also, I'm lazy and not preparing the
            # adapter because I assume encoding doesn't matter for these
            # objects.
            lower = adapt(r.lower).getquoted().decode("ascii")
        else:
            lower = ""

        if not r.upper_inf:
            upper = adapt(r.upper).getquoted().decode("ascii")
        else:
            upper = ""

        return ("'%s%s,%s%s'" % (r._bounds[0], lower, upper, r._bounds[1])).encode("ascii")
示例#30
0
    def test_seek_tell(self):
        lo = self.conn.lobject()
        length = lo.write(b("some data"))
        self.assertEqual(lo.tell(), length)
        lo.close()
        lo = self.conn.lobject(lo.oid)

        self.assertEqual(lo.seek(5, 0), 5)
        self.assertEqual(lo.tell(), 5)
        self.assertEqual(lo.read(), "data")

        # SEEK_CUR: relative current location
        lo.seek(5)
        self.assertEqual(lo.seek(2, 1), 7)
        self.assertEqual(lo.tell(), 7)
        self.assertEqual(lo.read(), "ta")

        # SEEK_END: relative to end of file
        self.assertEqual(lo.seek(-2, 2), length - 2)
        self.assertEqual(lo.read(), "ta")
示例#31
0
    def getquoted(self):
        r = self.adapted
        if r.isempty:
            return b("'empty'")

        if not r.lower_inf:
            # not exactly: we are relying that none of these object is really
            # quoted (they are numbers). Also, I'm lazy and not preparing the
            # adapter because I assume encoding doesn't matter for these
            # objects.
            lower = adapt(r.lower).getquoted().decode('ascii')
        else:
            lower = ''

        if not r.upper_inf:
            upper = adapt(r.upper).getquoted().decode('ascii')
        else:
            upper = ''

        return ("'%s%s,%s%s'" %
                (r._bounds[0], lower, upper, r._bounds[1])).encode('ascii')
示例#32
0
    def _getquoted_8(self):
        """Use the operators available in PG pre-9.0."""
        if not self.wrapped:
            return b("''::hstore")

        adapt = _ext.adapt
        rv = []
        for k, v in self.wrapped.iteritems():
            k = adapt(k)
            k.prepare(self.conn)
            k = k.getquoted()

            if v is not None:
                v = adapt(v)
                v.prepare(self.conn)
                v = v.getquoted()
            else:
                v = b('NULL')

            # XXX this b'ing is painfully inefficient!
            rv.append(b("(") + k + b(" => ") + v + b(")"))

        return b("(") + b('||').join(rv) + b(")")
示例#33
0
    def _getquoted_8(self):
        """Use the operators available in PG pre-9.0."""
        if not self.wrapped:
            return b("''::hstore")

        adapt = _ext.adapt
        rv = []
        for k, v in self.wrapped.iteritems():
            k = adapt(k)
            k.prepare(self.conn)
            k = k.getquoted()

            if v is not None:
                v = adapt(v)
                v.prepare(self.conn)
                v = v.getquoted()
            else:
                v = b('NULL')

            # XXX this b'ing is painfully inefficient!
            rv.append(b("(") + k + b(" => ") + v + b(")"))

        return b("(") + b('||').join(rv) + b(")")
示例#34
0
 def test_write_after_close(self):
     lo = self.conn.lobject()
     lo.close()
     self.assertRaises(psycopg2.InterfaceError, lo.write, b("some data"))
示例#35
0
 def test_adapt_bytes(self):
     snowman = u"\u2603"
     self.conn.set_client_encoding('utf8')
     a = psycopg2.extensions.QuotedString(snowman.encode('utf8'))
     a.prepare(self.conn)
     self.assertEqual(a.getquoted(), b("'\xe2\x98\x83'"))
示例#36
0
 def testByteaHexCheckFalsePositive(self):
     # the check \x -> x to detect bad bytea decode
     # may be fooled if the first char is really an 'x'
     o1 = psycopg2.Binary(b('x'))
     o2 = self.execute("SELECT %s::bytea AS foo", (o1,))
     self.assertEqual(b('x'), o2[0])
示例#37
0
 def testArrayMalformed(self):
     curs = self.conn.cursor()
     ss = ['', '{', '{}}', '{' * 20 + '}' * 20]
     for s in ss:
         self.assertRaises(psycopg2.DataError,
             psycopg2.extensions.STRINGARRAY, b(s), curs)
示例#38
0
 def test_blank_hex(self):
     # Reported as problematic in ticket #48
     rv = self.cast(b('\\x'))
     self.assertEqual(rv, b(''))
示例#39
0
 def test_blank(self):
     rv = self.cast(b(''))
     self.assertEqual(rv, b(''))
示例#40
0
 def test_open_for_write(self):
     lo = self.conn.lobject()
     lo2 = self.conn.lobject(lo.oid, "w")
     self.assertEqual(lo2.mode[0], "w")
     lo2.write(b("some data"))
示例#41
0
 def test_blank_hex(self):
     # Reported as problematic in ticket #48
     rv = self.cast(b('\\x'))
     self.assertEqual(rv, b(''))
示例#42
0
    def test_write_after_commit(self):
        lo = self.conn.lobject()
        self.lo_oid = lo.oid
        self.conn.commit()

        self.assertRaises(psycopg2.ProgrammingError, lo.write, b("some data"))
示例#43
0
 def getquoted(self):
     return b("'%s'::uuid" % self._uuid)
示例#44
0
 def test_write(self):
     lo = self.conn.lobject()
     self.assertEqual(lo.write(b("some data")), len("some data"))
示例#45
0
 def getquoted(self):
     obj = _A(self.addr)
     if hasattr(obj, 'prepare'):
         obj.prepare(self._conn)
     return obj.getquoted() + b("::inet")
示例#46
0
def filter_scs(conn, s):
    if conn.get_parameter_status("standard_conforming_strings") == 'off':
        return s
    else:
        return s.replace(b("E'"), b("'"))
示例#47
0
 def testArrayMalformed(self):
     curs = self.conn.cursor()
     ss = ['', '{', '{}}', '{' * 20 + '}' * 20]
     for s in ss:
         self.assertRaises(psycopg2.DataError,
             psycopg2.extensions.STRINGARRAY, b(s), curs)
示例#48
0
    def test_adapt_9(self):
        if self.conn.server_version < 90000:
            return self.skipTest("skipping dict adaptation with PG 9 syntax")

        from psycopg2.extras import HstoreAdapter

        o = {'a': '1', 'b': "'", 'c': None}
        if self.conn.encoding == 'UTF8':
            o['d'] = u'\xe0'

        a = HstoreAdapter(o)
        a.prepare(self.conn)
        q = a.getquoted()

        m = re.match(b(r'hstore\(ARRAY\[([^\]]+)\], ARRAY\[([^\]]+)\]\)'), q)
        self.assert_(m, repr(q))

        kk = m.group(1).split(b(", "))
        vv = m.group(2).split(b(", "))
        ii = zip(kk, vv)
        ii.sort()

        def f(*args):
            return tuple([filter_scs(self.conn, s) for s in args])

        self.assertEqual(len(ii), len(o))
        self.assertEqual(ii[0], f(b("E'a'"), b("E'1'")))
        self.assertEqual(ii[1], f(b("E'b'"), b("E''''")))
        self.assertEqual(ii[2], f(b("E'c'"), b("NULL")))
        if 'd' in o:
            encc = u'\xe0'.encode(
                psycopg2.extensions.encodings[self.conn.encoding])
            self.assertEqual(ii[3], f(b("E'd'"), b("E'") + encc + b("'")))
示例#49
0
 def test_encoding_default(self):
     from psycopg2.extensions import adapt
     a = adapt("hello")
     self.assertEqual(a.encoding, 'latin1')
     self.assertEqual(a.getquoted(), b("'hello'"))