Receitas do PostgreSQL: mecanismo de modelo de bigode

Para preparar o mecanismo de modelo de bigode, precisamos do postgres e do bigode . Você também pode usar a imagem finalizada .

Por que precisamos de um mecanismo de modelo no banco de dados? Bem, primeiro, se o mecanismo do modelo estiver no banco de dados, os próprios modelos também deverão estar no banco de dados. E por que você precisa armazenar modelos no banco de dados? Sim, porque modelos, como dados, também podem depender do tempo. Por exemplo, suponha que haja contas no banco de dados (são dados). Obviamente, eles dependem do tempo: este mês o valor é um, no próximo - outro, depois - no terceiro, etc. Mas o modelo de fatura também pode depender da hora: este ano um e no ano seguinte outro (como foi com a introdução de 20%). Portanto, é mais conveniente armazenar os próprios modelos no banco de dados. Bem, o mecanismo de modelo no banco de dados é conveniente porque você pode modelá-lo ali mesmo no banco de dados, depois (ali no banco de dados) converter para pdf e (ali no banco de dados) enviá-lo por email . E tudo isso pode ser feito de forma assíncrona usando o agendador.

O código não é muito grande, então eu publico tudo (com comentários)

#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"))); //        
    }
}

Usamos assim: primeiro crie uma extensão

create extension pg_mustach

e depois modelo na memória

select json2mustach('{"name":""}', ', {{name}}!')

ou arquivar

select json2mustach('{"name":""}', ', {{name}}!', 'file_name')

All Articles