Subject Re: [firebird-python] pack problem in Python 3
Author Pavel Cisar
Dne 12.1.2012 16:19, Philippe Makowski napsal(a):
> hum,
>
> this part of code is really important, and I am lost (but that's not
> really a surprise for me)
>
> if I do :
> def
> build_dpb(user,password,sql_dialect,role,charset,buffers,force_write,no_reserve,db_key_scope):
> params = [str(isc_dpb_version1)]
>
> def addString(codeAsByte, s):
> #assert isinstance(codeAsByte,types.IntType) and codeAsByte >= 0
> and codeAsByte <= 255
> sLen = len(s)
> if sLen >= 256:
> # Because the length is denoted in the DPB by a single byte.
> raise ProgrammingError("Individual component of database"
> " parameter buffer is too large. Components must be less"
> " than 256 bytes."
> )
> format = 'ii%ds' % sLen # like 'ii50s' for a 50-byte string
> newEntry = struct.pack(format, codeAsByte, sLen, s)
> params.append(newEntry.decode())
> def addInt(codeAsByte, value):
> #assert isinstance(codeAsByte,types.IntType) and codeAsByte >= 0
> and codeAsByte <= 255
> if not isinstance(value, int) or value < 0 or value > 255:
> raise ProgrammingError("The value for an integer DPB code
> must be"
> " an int or long with a value between 0 and 255."
> )
> newEntry = struct.pack('ipi', codeAsByte, b'\x01', value)
> params.append(newEntry.decode())
>
> if user:
> addString(isc_dpb_user_name,user.encode("utf8"))
> if password:
> addString(isc_dpb_password,password.encode("utf8"))
> if role:
> addString(isc_dpb_sql_role_name,role.encode("utf8"))
> if sql_dialect:
> addInt(isc_dpb_sql_dialect,sql_dialect)
> if charset:
> addString(isc_dpb_lc_ctype, charset.encode("utf8"))
> if buffers:
> addInt(isc_dpb_num_buffers,buffers)
> if force_write:
> addInt(isc_dpb_force_write,force_write)
> if no_reserve:
> addInt(isc_dpb_no_reserve,no_reserve)
> if db_key_scope:
> addInt(isc_dpb_dbkey_scope,db_key_scope)
> return ''.join(params)
>
> then I have a ctype error, of course
> ibase.isc_attach_database(_isc_status,len(dsn),dsn,_db_handle,len(dpb),dpb)
> ctypes.ArgumentError: argument 6: <class 'TypeError'>: wrong type
>
>
> so we really need to find how to fix this part of code for Python3
>
> build_dpb in fbcore have to be change
> but I don't know how yet :(

Which type is 'dpb' (the sixth parameter passed to isc_attach_database)
? It's bytes or str? In ctypes description, this parameter is of type
STRING, which allows passing Python strings easily (as is). In Python 2
it means type <str>, which is something different in Python 3.

So there are several possible scenarios:

1) We're passing <str> instead <bytes>, and ctypes.STRING means <bytes>.
Then we simply need to create 'dpb' as <bytes>.
2) We're passing <bytes>, but ctypes.STRING expects <str> under P3. Then
we have to change the definition for this parameter in IBASE to
something else (see 'buf_pointer' type and it's use in fbcore.py).

But I think that we're facing case 1 here.

BTW, the same case is with tpb.

best regards
Pavel Cisar