PageRenderTime 20ms CodeModel.GetById 9ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/examples/Mysql.winxed

http://github.com/NotFound/winxed
Unknown | 358 lines | 325 code | 33 blank | 0 comment | 0 complexity | 8b9c11e1923364d76659ecbe2fa074cc MD5 | raw file
  1#! winxed
  2
  3// Test Mysql usage via NCI
  4
  5// Note:
  6// null results from dlfuncs are checked in a convoluted way
  7// to be able to work with buggy versions of parrot.
  8
  9namespace WinxedMysql
 10{
 11
 12$include_const 'datatypes.pasm';
 13
 14// Severity and type of the exceptions explicitly thrown.
 15const int ERROR = 2;
 16const int TYPE= 99;
 17
 18namespace __private
 19{
 20
 21function findlib()
 22{
 23    for (string lib in [
 24                'libmysqlclient',
 25                'libmysqlclient.so.16',
 26                'libmysqlclient.so.15'
 27            ] ) {
 28        var l = loadlib(lib);
 29        if (l)
 30            return l;
 31    }
 32    return null;
 33}
 34
 35function getlib()
 36{
 37    var l = findlib();
 38    if (! l)
 39        throw Error('Cannot load Mysql lib', ERROR, TYPE);
 40    for (;;)
 41        yield l;
 42}
 43
 44function str_to_cstring(string s)
 45{
 46    var cstring = new ['ByteBuffer'];
 47    cstring =: s;
 48    push(cstring, 0);
 49    return cstring;
 50}
 51
 52} // namespace __private;
 53
 54using namespace __private;
 55
 56class Row
 57{
 58    var mrow;
 59    var desc;
 60    var nfields;
 61    var encoding;
 62    function Row(var myrow, var desc, int n, string encoding[optional])
 63    {
 64        self.mrow = myrow;
 65        self.desc = desc;
 66        self.nfields = n;
 67        if (encoding != null)
 68            self.encoding = encoding;
 69    }
 70    function get(int i)
 71    {
 72        string encoding;
 73        if (self.encoding != null)
 74            encoding = self.encoding;
 75        var p = self.desc[self.mrow, i];
 76        string result;
 77        if (p != null) {
 78            result = p.as_string(encoding);
 79        }
 80        else
 81            result = '';
 82        return result;
 83    }
 84}
 85
 86class Result
 87{
 88    var mysql;
 89    var myresult;
 90    var nfields;
 91    var desc;
 92    function Result(var my, var r)
 93    {
 94        using WinxedMysql.getlib;
 95        self.mysql = my;
 96        self.myresult = r;
 97        var f = dlfunc(getlib(), 'mysql_field_count', 'ip');
 98        int count = f(my.mysql);
 99        self.nfields = count;
100	int viewtype[count + 2] = [ DATATYPE_STRUCT, count ];
101	for (int i = 2; i < count + 2; ++i)
102            viewtype[i] = DATATYPE_PTR;
103        var desc = new ['StructView'] (viewtype);
104        self.desc = desc;
105    }
106    function field_count()
107    {
108        return self.nfields;
109    }
110    function fetch_row()
111    {
112        using WinxedMysql.getlib;
113        var f = dlfunc(getlib(), 'mysql_fetch_row', 'pp');
114        var frow = f(self.myresult);
115
116        if (frow == null)
117            return null;
118        var none = new 'UnManagedStruct';
119        if (frow == none)
120            return null;
121
122        string encoding;
123        if (self.mysql.encoding != null)
124            encoding = self.mysql.encoding;
125        return new WinxedMysql.Row(frow, self.desc, self.nfields, encoding);
126    }
127    function close()
128    {
129        if (self.myresult != null)
130        {
131            using WinxedMysql.getlib;
132            var f = dlfunc(getlib(), 'mysql_free_result', 'vp');
133            f(self.myresult);
134            self.myresult = null;
135        }
136    }
137}
138
139class Connection
140{
141    var mysql;
142    var encoding;
143
144    function Connection()
145    {
146        using WinxedMysql.getlib;
147        var minit = dlfunc(getlib(), 'mysql_init', 'pp');
148        string nothing;
149        var my = minit(null);
150        self.mysql = my;
151    }
152    function close()
153    {
154        using WinxedMysql.getlib;
155        var mclose = dlfunc(getlib(), 'mysql_close', 'vp');
156        mclose(self.mysql);
157        var n = new 'Undef';
158        self.mysql = n;
159    }
160    function get_client_info()
161    {
162        using WinxedMysql.getlib;
163        var f = dlfunc(getlib(), 'mysql_get_client_info', 'p');
164        return f().as_string('utf8');
165    }
166    function error()
167    {
168        using WinxedMysql.getlib;
169        var f = dlfunc(getlib(), 'mysql_error', 'pp');
170        return f(self.mysql).as_string('utf8');
171    }
172    function connect(string host, string user, string pass, string database,
173            string encoding)
174    {
175        using WinxedMysql.getlib;
176        var f = dlfunc(getlib(), 'mysql_real_connect', 'ppppppipi');
177        string snull;
178        var phost = str_to_cstring(host);
179        var puser = str_to_cstring(user);
180        var ppass = str_to_cstring(pass);
181        var pdatabase = str_to_cstring(database);
182        var p = f(self.mysql, phost, puser, ppass, pdatabase, 0, null, 0);
183        if (p == null)
184            throw Error(self.error(), ERROR, TYPE);
185        var none = new 'UnManagedStruct';
186        if (p == none)
187            throw Error(self.error(), ERROR, TYPE);
188
189        var setcharset = dlfunc(getlib(), 'mysql_set_character_set', 'ipp');
190        if (encoding != null) {
191            int i = setcharset(self.mysql, str_to_cstring(encoding));
192            if (i != 0)
193                cry('Failed to set character set.');
194           self.encoding = encoding;
195        }
196        return p;
197    }
198    function query(string stmt)
199    {
200        using WinxedMysql.getlib;
201        var f = dlfunc(getlib(), 'mysql_query', 'ipp');
202        var pstmt = str_to_cstring(stmt);
203        int q = f(self.mysql, pstmt);
204        if (q != 0)
205            throw Error(self.error(), ERROR, TYPE);
206    }
207    function use_result()
208    {
209        using WinxedMysql.getlib;
210        var f = dlfunc(getlib(), 'mysql_use_result', 'pp');
211        var r = f(self.mysql);
212        if (r == null)
213            throw Error(self.error(), ERROR, TYPE);
214        var none = new 'UnManagedStruct';
215        if (r == none)
216            throw Error(self.error(), ERROR, TYPE);
217        return new WinxedMysql.Result(self, r);
218    }
219}
220
221} // namespace WinxedMysql
222
223$load 'Getopt/Obj.pbc';
224
225function main(argv)
226{
227    using namespace WinxedMysql;
228
229    var getopts = new ['Getopt', 'Obj'];
230    getopts.notOptStop(1);
231    getopts.push_string('host|h=s');
232    getopts.push_string('user|u=s');
233    getopts.push_string('password|p:s');
234    getopts.push_string('database|D=s');
235    getopts.push_string('encoding|D=s');
236    getopts.push_string('config|D=s');
237    argv.shift();
238    var opts = getopts.get_options(argv);
239
240    string host;
241    string user;
242    string pass;
243    string database;
244    string encoding;
245
246    string config = opts['config'];
247    if (config != null && config != '') {
248        // Get config from file in json format.
249        try {
250            var json = load_language('data_json');
251            var code = json.compile(open(config).readall());
252            var data = code();
253            if (data['host'] != null)
254                host = data['host'];
255            if (data['user'] != null)
256                user = data['user'];
257            if (data['password'] != null)
258                pass = data['password'];
259            if (data['database'] != null)
260                database = data['database'];
261            if (data['encoding'] != null)
262                encoding = data['encoding'];
263        }
264        catch (e) {
265            cry('Error reading config file: ', e['message']);
266            return;
267        }
268    }
269
270    if (opts['host'] != null)
271        host = opts['host'];
272    if (opts['user'] != null)
273        user = opts['user'];
274    if (opts['password'] != null)
275        pass= opts['password'];
276    if (opts['database'] != null)
277        database = opts['database'];
278    if (opts['encoding'] != null)
279        encoding = opts['encoding'];
280
281    if (encoding != null) {
282        // Get the encoding number and get back the name from it.
283        // This simplifies the usage of encoding aliases and
284        // catch not available or invalid encodings.
285        int encnum;
286        try {
287            ${ find_encoding encnum, encoding };
288            ${ encodingname encoding, encnum };
289        }
290        catch() {
291            cry("Encoding '" + encoding + "' not available");
292            exit(1);
293        }
294    }
295
296    if (host == null || host == '')
297        host = 'localhost';
298    if (user == null || user == '')
299        user = 'parrot';
300
301    if (pass == null)
302        pass = 'baDworD';
303    else if (pass == '')
304        die("Sorry, asking for password not implemented");
305
306    if (database == null || database == '')
307        database = 'parrot';
308
309    var mysql = new WinxedMysql.Connection();
310    say('Mysql version: ', mysql.get_client_info());
311    var result;
312
313    try [min_severity(ERROR),max_severity(ERROR),handle_types(TYPE)] {
314        mysql.connect(host, user, pass, database, encoding);
315        string q = 'select * from hello;';
316        if (elements(argv) > 0) {
317            q = string(argv.shift());
318        }
319        for(;;) {
320        say("Query: '", q, "'");
321        mysql.query(q);
322        result = mysql.use_result();
323        int fields = result.field_count();
324
325        int nrows = 0;
326        var row;
327        while ((row = result.fetch_row()) != null) {
328            ++nrows;
329            print(nrows, ': ');
330            for (int i = 0; i < fields; ++i) {
331                if (i > 0)
332                    print(", ");
333                string s = row.get(i);
334                if (s == null)
335                    print('(null)');
336                else
337                    print("'", s, "'");
338            }
339            say();
340        }
341        result.close();
342        say('Total rows: ', nrows);
343        if (elements(argv) == 0)
344            break;
345        q = string(argv.shift());
346        }
347    }
348    catch (e) {
349        say("\tERROR: ", e['message']);
350        if (result != null)
351            result.close();
352        mysql.close();
353        return;
354    }
355    mysql.close();
356}
357
358// End