Recetas PostgreSQL: motor de plantillas de bigote

Para preparar el motor de plantillas de bigote, necesitamos postgres y bigote . También puedes usar la imagen terminada .

¿Por qué necesitamos un motor de plantillas en la base de datos? Bueno, en primer lugar, si el motor de plantillas está en la base de datos, entonces las plantillas mismas también deberían estar en la base de datos. ¿Y por qué necesita almacenar plantillas en la base de datos? Sí, porque las plantillas, como los datos, también pueden depender del tiempo. Por ejemplo, suponga que hay cuentas en la base de datos (esto son datos). Obviamente, dependen del tiempo: este mes la cantidad es uno, en el siguiente - otro, luego - el tercero, etc. Pero la plantilla de la factura también puede depender del tiempo: este año uno y el siguiente (como fue el caso con la introducción del 20%). Por lo tanto, es más conveniente almacenar las plantillas en la base de datos. Bueno, el motor de plantillas en la base de datos es conveniente ya que puede crear una plantilla allí mismo en la base de datos, luego (allí mismo en la base de datos) convertirlo a pdf y (allí mismo en la base de datos) enviarlo por correo electrónico . Y todo esto se puede hacer de forma asincrónica utilizando el programador.

El código no es demasiado grande, así que lo publico todo (con comentarios)

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

Lo usamos así: primero cree una extensión

create extension pg_mustach

y luego plantilla en memoria

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

o para archivar

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

All Articles