PostgreSQL рд░реЗрд╕рд┐рдкреА: рдорд╕реНрдЯреИрдЪ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди

рдорд╕реНрдЯ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдЗрдВрдЬрди рддреИрдпрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП , рд╣рдореЗрдВ рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдЬ рдФрд░ рдорд╕реНрдЯреИрдЪ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ ред рдЖрдк рддреИрдпрд╛рд░ рдЫрд╡рд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ ред

рд╣рдореЗрдВ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ? рдЦреИрд░, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЕрдЧрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╣реИ, рддреЛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЦреБрдж рднреА рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдФрд░ рдЖрдкрдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ? рд╣рд╛рдВ, рдХреНрдпреЛрдВрдХрд┐ рдбреЗрдЯрд╛ рдХреА рддрд░рд╣ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рднреА рд╕рдордп рдкрд░ рдирд┐рд░реНрднрд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдорд╛рди рд▓реЗрдВ рдХрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЦрд╛рддреЗ рд╣реИрдВ (рдпрд╣ рдбреЗрдЯрд╛ рд╣реИ)ред рдЬрд╛рд╣рд┐рд░ рд╣реИ, рд╡реЗ рд╕рдордп рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреЗ рд╣реИрдВ: рдЗрд╕ рдорд╣реАрдиреЗ рд░рд╛рд╢рд┐ рдПрдХ рд╣реИ, рдЕрдЧрд▓реЗ рдореЗрдВ - рдПрдХ рдФрд░, рдлрд┐рд░ - рддреАрд╕рд░рд╛, рдЖрджрд┐ред рд▓реЗрдХрд┐рди рдЗрдирд╡реЙрдЗрд╕ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕рдордп рдкрд░ рднреА рдирд┐рд░реНрднрд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ: рдЗрд╕ рд╕рд╛рд▓ рдПрдХ, рдФрд░ рджреВрд╕рд░рд╛ рджреВрд╕рд░рд╛ (рдЬреИрд╕рд╛ рдХрд┐ 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)) //   json_object
#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!"))); //      NULL
    if (PG_ARGISNULL(1)) ereport(ERROR, (errmsg("template is null!"))); //   - 
    json = TextDatumGetCString(PG_GETARG_DATUM(0)); //  C-   
    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!"))); //      NULL
            file = TextDatumGetCString(PG_GETARG_DATUM(2)); //  C-   
            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')

All Articles