--- parser3/src/classes/string.C 2001/07/23 11:19:25 1.65 +++ parser3/src/classes/string.C 2001/08/28 09:27:42 1.71 @@ -5,7 +5,7 @@ Author: Alexander Petrosyan (http://design.ru/paf) */ -static const char *RCSId="$Id: string.C,v 1.65 2001/07/23 11:19:25 parser Exp $"; +static const char *RCSId="$Id: string.C,v 1.71 2001/08/28 09:27:42 parser Exp $"; #include "classes.h" #include "pa_request.h" @@ -15,6 +15,7 @@ static const char *RCSId="$Id: string.C, #include "pa_vbool.h" #include "pa_string.h" #include "pa_sql_connection.h" +#include "pa_dictionary.h" // defines @@ -124,10 +125,10 @@ static void _lsplit(Request& r, const St Table& table=*new(pool) Table(pool, &string, &columns, pieces.size()); - int size=pieces.quick_size(); - for(int i=0; iget_junction(); - junction->rcontext=/*must be some way to get to - outside world junction->root=*/&vtable; + Value *saved_match_var_value=junction->root->get_element(*match_var_name); + junction->root->put_element(*match_var_name, &vtable); Value& replaced=ai.request->process(*ai.replacement_code, ai.origin, false); + junction->root->put_element(*match_var_name, saved_match_var_value); /* ai.dest->APPEND_CONST("("); @@ -303,7 +305,8 @@ public: String *result; }; #endif -const String* sql_result_string(Request& r, const String& method_name, MethodParams *params) { +const String* sql_result_string(Request& r, const String& method_name, MethodParams *params, + Hash *&options) { Pool& pool=r.pool(); if(!r.connection) @@ -313,7 +316,21 @@ const String* sql_result_string(Request& Value& statement=params->as_junction(0, "statement must be code"); - ulong offset=(ulong)(params->size()>2?params->as_int(2, r):0); + ulong limit=0; + ulong offset=0; + if(params->size()>1) { + Value& options_param=params->as_no_junction(1, "options must be hash, not code"); + if(options=options_param.get_hash()) { + if(Value *vlimit=(Value *)options->get(*sql_limit_name)) + limit=(ulong)r.process(*vlimit).as_double(); + if(Value *voffset=(Value *)options->get(*sql_offset_name)) + offset=(ulong)r.process(*voffset).as_double(); + } else + PTHROW(0, 0, + &method_name, + "options must be hash"); + } else + options=0; Temp_lang temp_lang(r, String::UL_SQL); const String& statement_string=r.process(statement).as_string(); @@ -323,7 +340,7 @@ const String* sql_result_string(Request& bool need_rethrow=false; Exception rethrow_me; PTRY { r.connection->query( - statement_cstr, offset, 0, + statement_cstr, offset, limit, handlers); } PCATCH(e) { // query problem @@ -344,19 +361,45 @@ const String* sql_result_string(Request& static void _sql(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); - const String *string=sql_result_string(r, method_name, params); + Hash *options; + const String *string=sql_result_string(r, method_name, params, options); if(!string) { - Value& default_code=params->as_junction(1, "default result must code"); - Value& processed_code=r.process(default_code); - string=processed_code.get_string(); - if(!string) - string=empty_string; + if(options) { + if(Value *vdefault=(Value *)options->get(*sql_default_name)) { + if(!vdefault->get_junction()) + PTHROW(0, 0, + &method_name, + "default option must be code"); + string=r.process(*vdefault).get_string(); + if(!string) + string=empty_string; + } else + PTHROW(0, 0, + &method_name, + "produced no result, but no default option specified"); + } else + PTHROW(0, 0, + &method_name, + "produced no result, but no options (no default) specified"); } VString& result=*new(pool) VString(*string); result.set_name(method_name); r.write_assign_lang(result); } +static void _replace(Request& r, const String& method_name, MethodParams *params) { + Pool& pool=r.pool(); + const String& src=*static_cast(r.self)->get_string(); + + Table *table=params->as_no_junction(0, "parameter must not be code").get_table(); + if(!table) + PTHROW(0, 0, + &method_name, + "parameter must be table"); + + Dictionary dict(*table); + r.write_assign_lang(*new(pool) VString(src.replace(pool, dict))); +} // constructor MString::MString(Pool& apool) : Methoded(apool) { @@ -399,9 +442,12 @@ MString::MString(Pool& apool) : Methoded // ^string.tolower[] add_native_method("lower", Method::CT_DYNAMIC, _lower, 0, 0); - // ^string:sql[query]{default} - // ^string:sql[query]{default}(offset) - add_native_method("sql", Method::CT_STATIC, _sql, 2, 3); + // ^sql[query] + // ^sql[query][$.limit(1) $.offset(2) $.default[n/a]] + add_native_method("sql", Method::CT_STATIC, _sql, 1, 2); + + // ^string.replace[table] + add_native_method("replace", Method::CT_DYNAMIC, _replace, 1, 1); } // global variable