Well, the fields of the table are not the same as the fields of the result of a
query!
AFAIK the "higher level" wrapper can't do what you want.
I once played around with it and wrote something like this:
import strutils, os
# NOTE: Some versions of the nim library have the wrong size for TFIELDS
import mysql
template mRaise(m: string) =
var e = new IOError
e.msg = m
raise e
template mRaise(con: PMySQL) =
var e = new IOError
e.msg = $ mysql.error(con)
raise e
template traceIt(m: string, doit: stmt): stmt =
echo "Trace: ", m
doit
proc showFields*(res: PRES) =
let fnum = int(mysql.numFields(res)) # cast string to int
#var fnames: seq[string]
#newSeq(fnames, fnum)
for i in 0.. <fnum:
let fp = mysql.fetch_field_direct(res, cast[cint](i))
case fp.ftype
of FIELD_TYPE_VAR_STRING: echo i, " ", fp.name, " (vstring)"
of FIELD_TYPE_STRING: echo i, " ", fp.name, " (string)"
of FIELD_TYPE_LONG: echo i, " ", fp.name, " (int32)"
of FIELD_TYPE_INT24: echo i, " ", fp.name, " (int24)"
of FIELD_TYPE_TINY: echo i, " ", fp.name, " (int8)"
of FIELD_TYPE_DECIMAL: echo i, " ", fp.name, " (decimal)"
of FIELD_TYPE_TIMESTAMP: echo i, " ", fp.name, " (timestamp)"
of FIELD_TYPE_DATE: echo i, " ", fp.name, " (date)"
of FIELD_TYPE_BLOB: echo i, " ", fp.name, " (binary)"
else: echo i, " ", fp.name, " (", fp.ftype, ")!!!!!!!!!!!!!!!!!!"
#fnames.add ($fp.name)
let con: PMySQL = mysql.init(nil)
if con == nil: mRaise "init failed"
if mysql.realConnect(con, "localhost", "root", "", "test", 0, nil, 0) ==
nil:
defer: traceIt "close con", mysql.close(con)
mRaise con
let q = "SELECT * FROM data"
if mysql.realQuery(con, q, q.len) != 0: mRaise con
#var res = mysql.storeResult(con)
var res = mysql.useResult(con)
if res != nil:
showFields res
#var f = cast[ptr array[2, TFIELD]](mysql.fetch_fields(res))
#quit 0
#echo res.row_count
#echo mysql.affected_rows con
#echo mysql.num_rows res
var row: cstringArray
while true:
row = mysql.fetchRow(res)
if row == nil: break
let fnum = int(mysql.numFields(res)) # cast string to int
for i in 0.. <fnum:
if row[i] == nil:
echo "NULL"
else:
echo row[i]
if row != nil:
while mysql.fetchRow(res) != nil: discard
mysql.freeResult(res)
Example:
-- Adminer 4.2.5 MySQL dump
SET NAMES utf8;
SET time_zone = '+00:00';
SET foreign_key_checks = 0;
SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
DROP TABLE IF EXISTS `data`;
CREATE TABLE `data` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`value` varchar(10) NOT NULL,
`ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP,
`en` enum('a','a','b','c') NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `data` (`id`, `value`, `ts`, `en`) VALUES
(1, 'c', '2014-11-14 12:17:10', 'a'),
(2, 'b', '2014-11-14 12:16:03', 'a');
-- 2016-07-28 13:16:14
Output:
0 id (int32)
1 value (vstring)
2 ts (timestamp)
3 en (string)
1
c
2014-11-14 13:17:10
a
2
b
2014-11-14 13:16:03
a
Still. You may consider that using a "free form" result with fieldnames is
probably not needed for what you want to do. Using PHP all day I also thought
that it is strange to not have access to the field names. But in a typed
language you want to get objects or tuples with typed fields back from the
database, not a bunch of strings associated to another bunch of strings. So
there is much more to this topic and highly dependent on what you really need
to do.