--- parser3/src/classes/hash.C 2001/05/10 14:00:18 1.1 +++ parser3/src/classes/hash.C 2001/05/21 16:38:46 1.3 @@ -5,21 +5,29 @@ Author: Alexander Petrosyan (http://design.ru/paf) - $Id: hash.C,v 1.1 2001/05/10 14:00:18 paf Exp $ + $Id: hash.C,v 1.3 2001/05/21 16:38:46 parser Exp $ */ #include "classes.h" #include "pa_request.h" #include "pa_vhash.h" #include "pa_vunknown.h" +#include "pa_sql_connection.h" + +// defines + +#define HASH_CLASS_NAME "hash" // class class MHash : public Methoded { +public: // VStateless_class + Value *create_new_value(Pool& pool) { return new(pool) VHash(pool); } + public: MHash(Pool& pool); public: // Methoded - bool used_directly() { return false; } + bool used_directly() { return true; } }; // methods @@ -36,12 +44,98 @@ static void _default(Request& r, const S } } +static void _sql(Request& r, const String& method_name, MethodParams *params) { + Pool& pool=r.pool(); + + if(!r.connection) + PTHROW(0, 0, + &method_name, + "without connect"); + + Value& statement=params->get_junction(0, "statement must be code"); + + ulong limit=0; + if(params->size()>1) { + Value& limit_code=params->get_junction(1, "limit must be expression"); + limit=(uint)r.process(limit_code).as_double(); + } + + ulong offset=0; + if(params->size()>2) { + Value& offset_code=params->get_junction(2, "offset must be expression"); + offset=(ulong)r.process(offset_code).as_double(); + } + + Temp_lang temp_lang(r, String::UL_SQL); + const String& statement_string=r.process(statement).as_string(); + const char *statement_cstr= + statement_string.cstr(String::UL_UNSPECIFIED, r.connection); + unsigned int sql_column_count; SQL_Driver::Cell *sql_columns; + unsigned long sql_row_count; SQL_Driver::Cell **sql_rows; + bool need_rethrow=false; Exception rethrow_me; + PTRY { + r.connection->query( + statement_cstr, offset, limit, + &sql_column_count, &sql_columns, + &sql_row_count, &sql_rows); + } + PCATCH(e) { // query problem + rethrow_me=e; need_rethrow=true; + } + PEND_CATCH + if(need_rethrow) + PTHROW(rethrow_me.type(), rethrow_me.code(), + &statement_string, // setting more specific source [were url] + rethrow_me.comment()); + + Hash& rows_hash=static_cast(r.self)->hash(); + rows_hash.clear(); + + if(sql_column_count<=1) + return; + + Array& columns=*new(pool) Array(pool); + for(unsigned int i=0+1; iAPPEND_TAINTED( + (const char *)sql_cells[i].ptr, sql_cells[i].size, + statement_cstr, row); + if(i==0) + key=cell; + else + row_hash.put(*columns.get_string(i-1), new(pool) VString(*cell)); + } + rows_hash.put(*key, &row_vhash); + } +} + // constructor MHash::MHash(Pool& apool) : Methoded(apool) { + set_name(*NEW String(pool(), HASH_CLASS_NAME)); + // ^hash.default[] // ^hash.default[hash] add_native_method("default", Method::CT_DYNAMIC, _default, 0, 1); + + // ^hash:sql[query][(count[;offset])] + add_native_method("sql", Method::CT_DYNAMIC, _sql, 1, 3); + } // global variable