Re: edbi on 64 bit machines?
- Posted by egis Apr 30, 2012
- 4021 views
I'm still getting some errors (I am looking into them and they are probably mine). However, is the following edbi_mysql.e file correct (based on the previous posts)?
See --vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv for the location of changes.
-- -- Copyright (C) 2009,2010 by Jeremy Cowgar <jeremy@cowgar.com> -- -- This file is part of edbi. -- -- edbi is free software: you can redistribute it and/or modify -- it under the terms of the GNU Lesser General Public License as -- published by the Free Software Foundation, either version 3 of -- the License, or (at your option) any later version. -- -- edbi is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public -- License along with edbi. If not, see <http://www.gnu.org/licenses/>. -- include std/datetime.e as dt include std/dll.e include std/error.e include std/get.e include std/machine.e include std/map.e include std/search.e include std/text.e include std/net/url.e include std/pretty.e include edbi/defs.e enum MYSQL_TYPE_DECIMAL=0, MYSQL_TYPE_TINY, MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG, MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24, MYSQL_TYPE_DATE, MYSQL_TYPE_TIME, MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR, MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, MYSQL_TYPE_BIT, MYSQL_TYPE_NEWDECIMAL=246, MYSQL_TYPE_ENUM=247, MYSQL_TYPE_SET=248, MYSQL_TYPE_TINY_BLOB=249, MYSQL_TYPE_MEDIUM_BLOB=250, MYSQL_TYPE_LONG_BLOB=251, MYSQL_TYPE_BLOB=252, MYSQL_TYPE_VAR_STRING=253, MYSQL_TYPE_STRING=254, MYSQL_TYPE_GEOMETRY=255 --vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv constant lib_mysql = open_dll({ "/usr/lib64/libmysqlclient.so.15", -- stupid hack for openeuphoria.org "libmysqlclient.so", "libmysqlclient.dylib", "libmysql.dll" }) --vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv ifdef BITS32 then constant MYSQL_FIELD_type = 76 elsedef constant MYSQL_FIELD_type = 112 end ifdef if lib_mysql = 0 then crash("Could not find a suitable MySQL shared library") end if constant h_mysql_init = define_c_func(lib_mysql, "mysql_init", {C_POINTER}, C_POINTER), h_mysql_real_connect = define_c_func(lib_mysql, "mysql_real_connect", { C_POINTER, C_POINTER, C_POINTER, C_POINTER, C_POINTER, C_UINT, C_POINTER, C_ULONG}, C_POINTER), h_mysql_close = define_c_proc(lib_mysql, "mysql_close", {C_POINTER}), h_mysql_error = define_c_func(lib_mysql, "mysql_error", {C_POINTER}, C_POINTER), h_mysql_errno = define_c_func(lib_mysql, "mysql_errno", {C_POINTER}, C_INT), h_mysql_real_query = define_c_func(lib_mysql, "mysql_real_query", {C_POINTER, C_POINTER, C_ULONG}, C_INT), h_mysql_field_count = define_c_func(lib_mysql, "mysql_field_count", {C_POINTER}, C_UINT), h_mysql_use_result = define_c_func(lib_mysql, "mysql_use_result", {C_POINTER}, C_POINTER), h_mysql_free_result = define_c_proc(lib_mysql, "mysql_free_result", {C_POINTER}), h_mysql_fetch_row = define_c_func(lib_mysql, "mysql_fetch_row", {C_POINTER}, C_POINTER), h_mysql_num_fields = define_c_func(lib_mysql, "mysql_num_fields", {C_POINTER}, C_UINT), h_mysql_fetch_lengths = define_c_func(lib_mysql, "mysql_fetch_lengths", {C_POINTER}, C_POINTER), h_mysql_insert_id = define_c_func(lib_mysql, "mysql_insert_id", {C_POINTER}, C_ULONG), h_mysql_fetch_field_direct = define_c_func(lib_mysql, "mysql_fetch_field_direct", {C_POINTER, C_INT}, C_POINTER), h_mysql_affected_rows = define_c_func(lib_mysql, "mysql_affected_rows", {C_POINTER}, C_INT) integer did_initialize = 0 function mysql_init(atom dbh=0) return c_func(h_mysql_init, {dbh}) end function include std/pretty.e public function edbi_open(sequence conn_str) object host, user, passwd, db, port, socket, flags conn_str = "mysql://" & conn_str object params = url:parse(conn_str, 0) host = params[URL_HOSTNAME] port = defaulted_value(params[URL_PORT], 0) db = params[URL_PATH][2..$] user = params[URL_USER] passwd = params[URL_PASSWORD] --socket = map:get(params[URL_QUERY_STRING], "socket", 0) --flags = map:get(params[URL_QUERY_STRING], "flags", 0) socket = 0 flags = 0 if port = 0 then port = 3306 end if if sequence(host) then host = allocate_string(host) end if if sequence(user) then user = allocate_string(user) end if if sequence(passwd) then passwd = allocate_string(passwd) end if if sequence(db) then db = allocate_string(db) end if if sequence(socket) then socket = allocate_string(socket) end if atom dbh = mysql_init() atom p_mysql = c_func(h_mysql_real_connect, {dbh, host, user, passwd, db, port, socket, flags}) free({ host, user, passwd, db }) if socket != 0 then free(socket) end if return p_mysql end function public procedure edbi_close(atom dbh) c_proc(h_mysql_close, {dbh}) end procedure public function edbi_error_code(atom dbh) return c_func(h_mysql_errno, {dbh}) end function public function edbi_error_message(atom dbh) sequence message = "" atom p_error = c_func(h_mysql_error, {dbh}) if p_error != NULL then -- Memory is free'd by MySQL when connection is closed message = peek_string(p_error) end if return message end function public function edbi_last_insert_id(atom dbh, sequence seq_name) seq_name = seq_name -- not used return c_func(h_mysql_insert_id, {dbh}) end function function mysql_field_count(atom dbh) return c_func(h_mysql_field_count, {dbh}) end function function mysql_use_result(atom dbh) return c_func(h_mysql_use_result, {dbh}) end function --vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv function mysql_fetch_field_direct(atom dbr, integer idx) atom p_f = c_func(h_mysql_fetch_field_direct, { dbr, idx }) sequence name = peek_string(peek_pointer(p_f)) integer typ = peek4u(p_f + MYSQL_FIELD_type) return { name, typ } end function public procedure edbi_closeq(atom dbr) c_proc(h_mysql_free_result, {dbr}) end procedure function mysql_num_fields(atom dbr) return c_func(h_mysql_num_fields, {dbr}) end function function mysql_fetch_lengths(atom dbr) return c_func(h_mysql_fetch_lengths, {dbr}) end function --vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv function peek_longu( object ptr ) ifdef LONG32 then return peek4u( ptr ) elsedef return peek8u( ptr ) end ifdef end function --vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv public function edbi_next(atom dbr, atom row) atom p_lengths, p_row = c_func(h_mysql_fetch_row, {dbr}) integer field_count object data = {}, tmp row = row -- not used if p_row = 0 then return 0 end if p_lengths = mysql_fetch_lengths(dbr) field_count = mysql_num_fields(dbr) integer row_offset = 0 integer len_offset = 0 for i = 0 to (field_count - 1) * sizeof( C_POINTER ) by sizeof( C_POINTER ) do data &= {peek({peek_pointer(p_row + row_offset), peek_longu(p_lengths + len_offset)})} row_offset += sizeof( C_POINTER ) len_offset += sizeof( C_LONG ) end for return data end function public function edbi_execute(atom dbh, sequence sql) atom p_sql = allocate_string(sql) integer result = c_func(h_mysql_real_query, {dbh, p_sql, length(sql)}) free(p_sql) return result end function public function edbi_total_changes(atom dbh) return c_func(h_mysql_affected_rows, { dbh }) end function public function edbi_query(atom dbh, sequence sql) integer q_result = edbi_execute(dbh, sql) if not q_result = 0 then return 0 end if atom dbr = mysql_use_result(dbh) sequence fdata = repeat(0, mysql_num_fields(dbr)) for i = 1 to length(fdata) do object f = mysql_fetch_field_direct(dbr, i - 1) integer ftype = EU_SEQUENCE -- Default is a SEQUENCE switch f[2] do case MYSQL_TYPE_DECIMAL, MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, MYSQL_TYPE_NEWDECIMAL then ftype = EU_ATOM case MYSQL_TYPE_TINY, MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG, MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24 then ftype = EU_INTEGER case MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_DATE, MYSQL_TYPE_TIME, MYSQL_TYPE_DATETIME then ftype = EU_DATETIME end switch fdata[i] = { f[1], ftype } end for return { dbr, fdata } end function