From 8a37534b574460dd4be6b3c18ad31faae054950d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?= <grubba@grubba.org> Date: Thu, 6 Mar 1997 22:21:03 +0100 Subject: [PATCH] Used to be part of sql.pre.pike. Rev: lib/modules/Sql.pmod/sql.pike:1.1 Rev: lib/modules/Sql.pmod/sql_result.pike:1.1 --- .gitattributes | 2 + lib/modules/Sql.pmod/sql.pike | 239 +++++++++++++++++++++++++++ lib/modules/Sql.pmod/sql_result.pike | 93 +++++++++++ 3 files changed, 334 insertions(+) create mode 100644 lib/modules/Sql.pmod/sql.pike create mode 100644 lib/modules/Sql.pmod/sql_result.pike diff --git a/.gitattributes b/.gitattributes index 01cc6f292d..86550f50ee 100644 --- a/.gitattributes +++ b/.gitattributes @@ -19,6 +19,8 @@ testfont binary /lib/modules/LR.pmod/scanner.pike foreign_ident /lib/modules/Sql.pmod/mysql.pike foreign_ident /lib/modules/Sql.pmod/mysql_result.pike foreign_ident +/lib/modules/Sql.pmod/sql.pike foreign_ident +/lib/modules/Sql.pmod/sql_result.pike foreign_ident /src/backend.c foreign_ident /src/builtin_functions.c foreign_ident /src/configure.in foreign_ident diff --git a/lib/modules/Sql.pmod/sql.pike b/lib/modules/Sql.pmod/sql.pike new file mode 100644 index 0000000000..33b08c6c07 --- /dev/null +++ b/lib/modules/Sql.pmod/sql.pike @@ -0,0 +1,239 @@ +/* + * $Id: sql.pike,v 1.1 1997/03/06 21:21:02 grubba Exp $ + * + * Implements the generic parts of the SQL-interface + * + * Henrik Grubbstr�m 1996-01-09 + */ + +#define throw_error(X) throw(({ (X), backtrace() })) + +import Array; +import Simulate; + +object master_sql; + +void create(void|string|object host, void|string db, + void|string user, void|string password) +{ + if (objectp(host)) { + master_sql = host; + if ((user && user != "") || (password && password != "")) { + throw_error("Sql(): Only the database argument is supported when " + "first argument is an object\n"); + } + if (db && db != "") { + master_sql->select_db(db); + } + return; + } else { + foreach(get_dir(Sql->dirname), string program_name) { + if (sizeof(program_name / "_result") == 1 && + (program_name != "Sql.pike")) { + /* Don't call ourselves... */ + array(mixed) err; + + err = catch { + program p = Sql[program_name]; + + if (password && password != "") { + master_sql = p(host||"", db||"", user||"", password); + } else if (user && user != "") { + master_sql = p(host||"", db||"", user); + } else if (db && db != "") { + master_sql = p(host||"", db); + } else if (host && host != "") { + master_sql = p(host); + } else { + master_sql = p(); + } + return; + }; + } + } + } + + throw_error("Sql(): Couldn't connect to database\n"); +} + +static private array(mapping(string:mixed)) res_obj_to_array(object res_obj) +{ + if (res_obj) { + /* Not very efficient, but sufficient */ + array(mapping(string:mixed)) res = ({}); + array(string) fieldnames; + array(mixed) row; + + fieldnames = map(res_obj->fetch_fields(), + lambda (mapping(string:mixed) m) { + return(m->name); /* Hope this is unique */ + } ); + + while (row = res_obj->fetch_row()) { + res += ({ mkmapping(fieldnames, row) }); + } + return(res); + } else { + return(0); + } +} + +int|string error() +{ + return(master_sql->error()); +} + +void select_db(string db) +{ + master_sql->select_db(db); +} + +array(mapping(string:mixed)) query(string s) +{ + object res_obj; + + if (functionp(master_sql->query)) { + return(master_sql->query(s)); + } + return(res_obj_to_array(master_sql->big_query(s))); +} + +object big_query(string q) +{ + if (functionp(master_sql->big_query)) { + return(Sql.Sql_result(master_sql->big_query(q))); + } + return(Sql.Sql_result(master_sql->query(q))); +} + +void create_db(string db) +{ + master_sql->create_db(db); +} + +void drop_db(string db) +{ + master_sql->drop_db(db); +} + +void shutdown() +{ + if (functionp(master_sql->shutdown)) { + master_sql->shutdown(); + } else { + throw_error("sql->shutdown(): Not supported by this database\n"); + } +} + +void reload() +{ + if (functionp(master_sql->reload)) { + master_sql->reload(); + } else { + /* Probably safe to make this a NOOP */ + } +} + +string server_info() +{ + if (functionp(master_sql->server_info)) { + return(master_sql->server_info()); + } + return("Unknown SQL-server"); +} + +string host_info() +{ + if (functionp(master_sql->host_info)) { + return(master_sql->host_info()); + } + return("Unknown connection to host"); +} + +array(string) list_dbs(string|void wild) +{ + array(string)|array(mapping(string:mixed))|object res; + + if (functionp(master_sql->list_dbs)) { + if (objectp(res = master_sql->list_dbs())) { + res = res_obj_to_array(res); + } + } else { + res = query("show databases"); + } + if (sizeof(res) && mappingp(res[0])) { + res = map(res, lambda (mapping m) { + return(values(m)[0]); /* Hope that there's only one field */ + } ); + } + if (wild) { + res = map_regexp(res, replace(wild, ({ "%", "_" }), ({ ".*", "." }) )); + } + return(res); +} + +array(string) list_tables(string|void wild) +{ + array(string)|array(mapping(string:mixed))|object res; + + if (functionp(master_sql->list_tables)) { + if (objectp(res = master_sql->list_tables())) { + res = res_obj_to_array(res); + } + } else { + res = query("show tables"); + } + if (sizeof(res) && mappingp(res[0])) { + res = map(res, lambda (mapping m) { + return(values(m)[0]); /* Hope that there's only one field */ + } ); + } + if (wild) { + res = map_regexp(res, replace(wild, ({ "%", "_" }), ({ ".*", "." }) )); + } + return(res); +} + +array(mapping(string:mixed)) list_fields(string table, string|void wild) +{ + array(mapping(string:mixed))|object res; + + if (functionp(master_sql->list_fields)) { + if (objectp(res = master_sql->list_fields(table))) { + res = res_obj_to_array(res); + } + if (wild) { + /* Not very efficient, but... */ + res = filter(res, lambda (mapping m, string re) { + return(sizeof(map_regexp( ({ m->name }), re))); + }, replace(wild, ({ "%", "_" }), ({ ".*", "." }) ) ); + } + return(res); + } + if (wild) { + res = query("show fields from \'" + table + + "\' like \'" + wild + "\'"); + } else { + res = query("show fields from \'" + table + "\'"); + } + res = map(res, lambda (mapping m, string table) { + foreach(indices(m), string str) { + /* Add the lower case variants */ + string low_str = lower_case(str); + if (low_str != str && !m[low_str]) { + m[low_str] = m[str]; + m_delete(m, str); /* Remove duplicate */ + } + } + if ((!m->name) && m->field) { + m["name"] = m->field; + m_delete(m, "field"); /* Remove duplicate */ + } + if (!m->table) { + m["table"] = table; + } + return(m); + }, table); + return(res); +} + diff --git a/lib/modules/Sql.pmod/sql_result.pike b/lib/modules/Sql.pmod/sql_result.pike new file mode 100644 index 0000000000..74851bbba1 --- /dev/null +++ b/lib/modules/Sql.pmod/sql_result.pike @@ -0,0 +1,93 @@ +/* + * $Id: sql_result.pike,v 1.1 1997/03/06 21:21:03 grubba Exp $ + * + * Implements the generic result module of the SQL-interface + * + * Henrik Grubbstr�m 1996-01-09 + */ + +#define throw_error(X) throw(({ (X), backtrace() })) + +object|array master_res; +int index; + +import Array; + +void create(object|array res) +{ + if (!(master_res = res) || (!arrayp(res) && !objectp(res))) { + throw_error("Bad arguments to Sql_result()\n"); + } + index = 0; +} + +int num_rows() +{ + if (arrayp(master_res)) { + return(sizeof(master_res)); + } + return(master_res->num_rows()); +} + +int num_fields() +{ + if (arrayp(master_res)) { + return(sizeof(master_res[0])); + } + return(master_res->num_fields()); +} + +int eof() +{ + if (arrayp(master_res)) { + return(index >= sizeof(master_res)); + } + return(master_res->eof()); +} + +array(mapping(string:mixed)) fetch_fields() +{ + if (arrayp(master_res)) { + /* Only supports the name field */ + array(mapping(string:mixed)) res = allocate(sizeof(master_res)); + int index = 0; + + foreach(sort(indices(master_res)), string name) { + res[index++] = ([ "name": name ]); + } + return(res); + } + return(master_res->fetch_fields()); +} + +void seek(int skip) +{ + if (skip < 0) { + throw_error("seek(): Argument 1 not positive\n"); + } + if (arrayp(master_res)) { + index += skip; + } else if (functionp(master_res->seek)) { + master_res->seek(index); + } else { + while (skip--) { + master_res->fetch_row(); + } + } +} + +int|array(string|int) fetch_row() +{ + if (arrayp(master_res)) { + array res; + + if (index >= sizeof(master_res)) { + return(0); + } + sort(indices(master_res[index]), res = values(master_res[index])); + return(res); + } + return (master_res->fetch_row()); +} + + -- GitLab