рдорд╕реНрдЯ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдЗрдВрдЬрди рддреИрдпрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП , рд╣рдореЗрдВ рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдЬ рдФрд░ рдорд╕реНрдЯреИрдЪ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ ред рдЖрдк рддреИрдпрд╛рд░ рдЫрд╡рд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ редрд╣рдореЗрдВ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ? рдЦреИрд░, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЕрдЧрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╣реИ, рддреЛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЦреБрдж рднреА рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдФрд░ рдЖрдкрдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ? рд╣рд╛рдВ, рдХреНрдпреЛрдВрдХрд┐ рдбреЗрдЯрд╛ рдХреА рддрд░рд╣ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рднреА рд╕рдордп рдкрд░ рдирд┐рд░реНрднрд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдорд╛рди рд▓реЗрдВ рдХрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЦрд╛рддреЗ рд╣реИрдВ (рдпрд╣ рдбреЗрдЯрд╛ рд╣реИ)ред рдЬрд╛рд╣рд┐рд░ рд╣реИ, рд╡реЗ рд╕рдордп рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреЗ рд╣реИрдВ: рдЗрд╕ рдорд╣реАрдиреЗ рд░рд╛рд╢рд┐ рдПрдХ рд╣реИ, рдЕрдЧрд▓реЗ рдореЗрдВ - рдПрдХ рдФрд░, рдлрд┐рд░ - рддреАрд╕рд░рд╛, рдЖрджрд┐ред рд▓реЗрдХрд┐рди рдЗрдирд╡реЙрдЗрд╕ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕рдордп рдкрд░ рднреА рдирд┐рд░реНрднрд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ: рдЗрд╕ рд╕рд╛рд▓ рдПрдХ, рдФрд░ рджреВрд╕рд░рд╛ рджреВрд╕рд░рд╛ (рдЬреИрд╕рд╛ рдХрд┐ 20% рдХреА рд╢реБрд░реВрдЖрдд рдХреЗ рд╕рд╛рде рд╣реБрдЖ рдерд╛)ред рдЗрд╕рд▓рд┐рдП, рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╕реНрд╡рдпрдВ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдирд╛ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рдЦреИрд░, рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдЗрд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╡рд╣реАрдВ рдкрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдлрд┐рд░ (рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╡рд╣реАрдВ) рдкреАрдбреАрдПрдл рдореЗрдВ рдХрдирд╡рд░реНрдЯ рдХрд░реЗрдВ рдФрд░ (рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╡рд╣реАрдВ) рдЗрд╕реЗ рдИрдореЗрд▓ рджреНрд╡рд╛рд░рд╛ рднреЗрдЬреЗрдВ ред рдФрд░ рдпрд╣ рд╕рдм рд╢реЗрдбреНрдпреВрд▓рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд░реВрдк рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИредрдХреЛрдб рдмрд╣реБрдд рдмрдбрд╝рд╛ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдпрд╣ рд╕рдм (рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде) рдкреЛрд╕реНрдЯ рдХрд░рддрд╛ рд╣реВрдВ#include <postgres.h> // .
#include <catalog/pg_type.h> //
extern text *cstring_to_text(const char *s);
extern text *cstring_to_text_with_len(const char *s, int len);
extern char *text_to_cstring(const text *t);
extern void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len);
#define CStringGetTextDatum(s) PointerGetDatum(cstring_to_text(s))
#define TextDatumGetCString(d) text_to_cstring((text *) DatumGetPointer(d))
#include <mustach/mustach-json-c.h> //
#define EXTENSION(function) Datum (function)(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(function); Datum (function)(PG_FUNCTION_ARGS)
PG_MODULE_MAGIC;
EXTENSION(json2mustach) {
char *file;
char *json;
char *output_data;
char *template;
enum json_tokener_error error;
FILE *out;
size_t output_len;
struct json_object *object;
text *output;
if (PG_ARGISNULL(0)) ereport(ERROR, (errmsg("json is null!")));
if (PG_ARGISNULL(1)) ereport(ERROR, (errmsg("template is null!")));
json = TextDatumGetCString(PG_GETARG_DATUM(0));
template = TextDatumGetCString(PG_GETARG_DATUM(1));
if (!(object = json_tokener_parse_verbose(json, &error))) ereport(ERROR, (errmsg("!json_tokener_parse and %s", json_tokener_error_desc(error))));
switch (PG_NARGS()) {
case 2: if (!(out = open_memstream(&output_data, &output_len))) ereport(ERROR, (errmsg("!open_memstream"))); break;
case 3:
if (PG_ARGISNULL(2)) ereport(ERROR, (errmsg("file is null!")));
file = TextDatumGetCString(PG_GETARG_DATUM(2));
if (!(out = fopen(file, "wb"))) ereport(ERROR, (errmsg("!fopen")));
pfree(file);
break;
default: ereport(ERROR, (errmsg("expect be 2 or 3 args")));
}
if (fmustach_json_c(template, object, out)) ereport(ERROR, (errmsg("fmustach_json_c")));
pfree(json);
pfree(template);
if (!json_object_put(object)) ereport(ERROR, (errmsg("!json_object_put")));
switch (PG_NARGS()) {
case 2:
fclose(out);
output = cstring_to_text_with_len(output_data, output_len);
free(output_data);
PG_RETURN_TEXT_P(output);
break;
case 3: PG_RETURN_BOOL(true); break;
default: ereport(ERROR, (errmsg("expect be 2 or 3 args")));
}
}
рд╣рдо рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ: рдкрд╣рд▓реЗ рдПрдХ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдмрдирд╛рдПрдВcreate extension pg_mustach
рдФрд░ рдлрд┐рд░ рдореЗрдореЛрд░реА рдореЗрдВ рдЯреЗрдореНрдкрд▓реЗрдЯselect json2mustach('{"name":""}', ', {{name}}!')
рдпрд╛ рдлрд╛рдЗрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПselect json2mustach('{"name":""}', ', {{name}}!', 'file_name')