Recettes PostgreSQL: moteur de modèle de moustache

Pour préparer le moteur de modèle de moustache, nous avons besoin de postgres et de moustache . Vous pouvez également utiliser l' image finie .

Pourquoi avons-nous besoin d'un moteur de modèle dans la base de données? Eh bien, tout d'abord, si le moteur de modèle est dans la base de données, les modèles eux-mêmes devraient également être dans la base de données. Et pourquoi avez-vous besoin de stocker des modèles dans la base de données? Oui, car les modèles, comme les données, peuvent également dépendre du temps. Par exemple, supposons qu'il existe des comptes dans la base de données (il s'agit de données). Évidemment, ils dépendent du temps: ce mois-ci le montant est un, dans le suivant - un autre, puis - le troisième, etc. Mais le modèle de facture peut aussi dépendre du temps: cette année une, et la suivante une autre (comme ce fut le cas avec l'introduction de 20%). Par conséquent, il est plus pratique de stocker les modèles eux-mêmes dans la base de données. Eh bien, le moteur de modèle dans la base de données est pratique car vous pouvez le créer directement dans la base de données, puis (là dans la base de données) le convertir en pdf et (directement dans la base de données) l' envoyer par e-mail . Et tout cela peut être fait de manière asynchrone en utilisant le planificateur.

Le code n'est pas trop gros, donc je poste tout (avec commentaires)

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

Nous l'utilisons comme ceci: créez d'abord une extension

create extension pg_mustach

puis modèle en mémoire

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

ou déposer

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

All Articles