Skip to content

Commit

Permalink
feat: sections for bool and non-null variables
Browse files Browse the repository at this point in the history
  • Loading branch information
steve-chavez committed Nov 12, 2023
1 parent 90e8f60 commit 1fa9c1d
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 10 deletions.
40 changes: 30 additions & 10 deletions src/plmustache.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
PG_MODULE_MAGIC;

typedef struct {
char *prm_name;
char *prm_value;
char *prm_name;
char *prm_value;
bool enters_section;
} plmustache_param;

typedef struct {
Expand All @@ -34,12 +35,22 @@ typedef struct {
char** argnames;
} plmustache_call_info;

// TODO these are used to handle sections, they're mandatory otherwise mustach segfaults
static int
plmustache_enter(void *closure, const char *value){
return MUSTACH_OK;
plmustache_enter_section(void *userdata, const char *name){
plmustache_ctx *ctx = (plmustache_ctx *)userdata;

for(size_t i = 0; i < ctx->num_params; i++){
plmustache_param* prm = &ctx->params[i];

if(strcmp(prm->prm_name, name) == 0){
return prm->enters_section;
}
}

return 0;
}

// TODO these are used to handle sections, they're mandatory otherwise mustach segfaults
static int plmustache_next(void *closure){
return MUSTACH_OK;
}
Expand All @@ -49,9 +60,8 @@ plmustache_leave(void *closure){
return MUSTACH_OK;
}

// handles mustache variables
static int
plmustache_get(void *userdata, const char *name, struct mustach_sbuf *sbuf){
plmustache_get_variable(void *userdata, const char *name, struct mustach_sbuf *sbuf){
plmustache_ctx *ctx = (plmustache_ctx *)userdata;

for(size_t i = 0; i < ctx->num_params; i++){
Expand Down Expand Up @@ -133,10 +143,10 @@ Datum plmustache_handler(PG_FUNCTION_ARGS)
int mustach_code;
size_t mustache_result_size;
struct mustach_itf itf = {
.enter = plmustache_enter,
.enter = plmustache_enter_section,
.next = plmustache_next,
.leave = plmustache_leave,
.get = plmustache_get,
.get = plmustache_get_variable,
};

plmustache_call_info call_info = validate_build_call_info(function_oid, fcinfo);
Expand All @@ -149,7 +159,17 @@ Datum plmustache_handler(PG_FUNCTION_ARGS)

for(size_t i = 0; i < call_info.numargs; i++){
params[i].prm_name = call_info.argnames[i];
params[i].prm_value = datum_to_cstring(fcinfo->args[i].value, call_info.argtypes[i]);
NullableDatum arg = fcinfo->args[i];
if(arg.isnull){
params[i].prm_value = NULL;
params[i].enters_section = false;
}else{
params[i].prm_value = datum_to_cstring(arg.value, call_info.argtypes[i]);
if(call_info.argtypes[i] == BOOLOID)
params[i].enters_section = DatumGetBool(arg.value);
else
params[i].enters_section = true;
}
}

mustach_code = mustach_mem(template, 0, &itf, &ctx, 0, &mustache_result, &mustache_result_size);
Expand Down
81 changes: 81 additions & 0 deletions test/expected/sections.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
create extension if not exists plmustache;
NOTICE: extension "plmustache" already exists, skipping
\echo

create or replace function bool_section(x1 text, x2 bool) returns text as $$
Section: {{#x2}}Show {{x1}}{{/x2}}
$$ language plmustache;
\echo

select bool_section('Something', true);
bool_section
-------------------------
Section: Show Something
(1 row)

select bool_section('Something', false);
bool_section
--------------
Section:
(1 row)

create or replace function bool_section_inverted(x1 text, x2 bool) returns text as $$
Section: Show {{#x2}}{{x1}}{{/x2}}{{^x2}}Nothing{{/x2}}
$$ language plmustache;
\echo

select bool_section_inverted('Something', true);
bool_section_inverted
-------------------------
Section: Show Something
(1 row)

select bool_section_inverted('Something', false);
bool_section_inverted
-----------------------
Section: Show Nothing
(1 row)

create or replace function foo_test(foo text) returns text as $$
{{#foo}}foo is {{foo}}{{/foo}}
$$ language plmustache;
\echo

select foo_test('bar');
foo_test
------------
foo is bar
(1 row)

create or replace function foo_test(foo bool) returns text as $$
foo is {{#foo}}{{foo}}{{/foo}}{{^foo}}{{foo}}{{/foo}}
$$ language plmustache;
\echo

select foo_test(true);
foo_test
----------
foo is t
(1 row)

select foo_test(false);
foo_test
----------
foo is f
(1 row)

create or replace function foo_null_test(foo bool) returns text as $$
foo is {{#foo}}full{{/foo}}{{^foo}}null{{/foo}}
$$ language plmustache;
select foo_null_test(null);
foo_null_test
---------------
foo is null
(1 row)

select foo_null_test(true);
foo_null_test
---------------
foo is full
(1 row)

44 changes: 44 additions & 0 deletions test/sql/sections.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
create extension if not exists plmustache;
\echo

create or replace function bool_section(x1 text, x2 bool) returns text as $$
Section: {{#x2}}Show {{x1}}{{/x2}}
$$ language plmustache;
\echo

select bool_section('Something', true);

select bool_section('Something', false);

create or replace function bool_section_inverted(x1 text, x2 bool) returns text as $$
Section: Show {{#x2}}{{x1}}{{/x2}}{{^x2}}Nothing{{/x2}}
$$ language plmustache;
\echo

select bool_section_inverted('Something', true);

select bool_section_inverted('Something', false);

create or replace function foo_test(foo text) returns text as $$
{{#foo}}foo is {{foo}}{{/foo}}
$$ language plmustache;
\echo

select foo_test('bar');

create or replace function foo_test(foo bool) returns text as $$
foo is {{#foo}}{{foo}}{{/foo}}{{^foo}}{{foo}}{{/foo}}
$$ language plmustache;
\echo

select foo_test(true);

select foo_test(false);

create or replace function foo_null_test(foo bool) returns text as $$
foo is {{#foo}}full{{/foo}}{{^foo}}null{{/foo}}
$$ language plmustache;

select foo_null_test(null);

select foo_null_test(true);

0 comments on commit 1fa9c1d

Please sign in to comment.