Kouhei Sutou
null+****@clear*****
Sat Apr 23 15:41:07 JST 2016
Kouhei Sutou 2016-04-23 15:41:07 +0900 (Sat, 23 Apr 2016) New Revision: 7243d24142586b34c1448af2630f3fae95d0ef73 https://github.com/pgroonga/pgroonga/commit/7243d24142586b34c1448af2630f3fae95d0ef73 Message: Split code for pgroonga.snippet_html Added files: src/pgrn_snippet_html.c Modified files: CMakeLists.txt Makefile src/pgroonga.c Modified: CMakeLists.txt (+1 -0) =================================================================== --- CMakeLists.txt 2016-04-23 15:32:40 +0900 (8a13f44) +++ CMakeLists.txt 2016-04-23 15:41:07 +0900 (c3ef069) @@ -64,6 +64,7 @@ set(PGRN_SOURCES "src/pgrn_groonga.c" "src/pgrn_jsonb.c" "src/pgrn_options.c" + "src/pgrn_snippet_html.c" "src/pgrn_value.c" "src/pgrn_variables.c" "vendor/xxHash/xxhash.c") Modified: Makefile (+1 -0) =================================================================== --- Makefile 2016-04-23 15:32:40 +0900 (8b0b975) +++ Makefile 2016-04-23 15:41:07 +0900 (f161ea8) @@ -11,6 +11,7 @@ SRCS = \ src/pgrn_groonga.c \ src/pgrn_jsonb.c \ src/pgrn_options.c \ + src/pgrn_snippet_html.c \ src/pgrn_value.c \ src/pgrn_variables.c \ vendor/xxHash/xxhash.c Added: src/pgrn_snippet_html.c (+139 -0) 100644 =================================================================== --- /dev/null +++ src/pgrn_snippet_html.c 2016-04-23 15:41:07 +0900 (27cd254) @@ -0,0 +1,139 @@ +#include "pgroonga.h" + +#include "pgrn_global.h" +#include "pgrn_groonga.h" + +#include <catalog/pg_type.h> +#include <utils/array.h> +#include <utils/builtins.h> + +static grn_ctx *ctx = &PGrnContext; + +static grn_obj * +PGrnSnipCreate(ArrayType *keywords) +{ + grn_obj *snip; + int flags = GRN_SNIP_SKIP_LEADING_SPACES; + unsigned int width = 200; + unsigned int maxNResults = 3; + const char *openTag = "<span class=\"keyword\">"; + const char *closeTag = "</span>"; + grn_snip_mapping *mapping = GRN_SNIP_MAPPING_HTML_ESCAPE; + + snip = grn_snip_open(ctx, flags, width, maxNResults, + openTag, strlen(openTag), + closeTag, strlen(closeTag), + mapping); + if (!snip) + { + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("pgroonga: " + "failed to allocate memory for generating snippet"))); + return NULL; + } + + grn_snip_set_normalizer(ctx, snip, GRN_NORMALIZER_AUTO); + + { + int i, n; + + n = ARR_DIMS(keywords)[0]; + for (i = 1; i <= n; i++) + { + Datum keywordDatum; + text *keyword; + bool isNULL; + + keywordDatum = array_ref(keywords, 1, &i, -1, -1, false, + 'i', &isNULL); + if (isNULL) + continue; + + keyword = DatumGetTextPP(keywordDatum); + grn_snip_add_cond(ctx, snip, + VARDATA_ANY(keyword), + VARSIZE_ANY_EXHDR(keyword), + NULL, 0, NULL, 0); + } + } + + return snip; +} + +static grn_rc +PGrnSnipExec(grn_obj *snip, text *target, ArrayType **snippetArray) +{ + grn_rc rc; + unsigned int i, nResults, maxTaggedLength; + char *buffer; + Datum *snippets; + int dims[1]; + int lbs[1]; + + rc = grn_snip_exec(ctx, snip, + VARDATA_ANY(target), + VARSIZE_ANY_EXHDR(target), + &nResults, &maxTaggedLength); + if (rc != GRN_SUCCESS) + { + return rc; + } + + if (nResults == 0) + { + *snippetArray = construct_empty_array(TEXTOID); + return GRN_SUCCESS; + } + + buffer = palloc(sizeof(char) * maxTaggedLength); + snippets = palloc(sizeof(Datum) * nResults); + for (i = 0; i < nResults; i++) + { + grn_rc rc; + unsigned int snippetLength = 0; + + rc = grn_snip_get_result(ctx, snip, i, buffer, &snippetLength); + if (rc != GRN_SUCCESS) + { + pfree(buffer); + return rc; + } + snippets[i] = PointerGetDatum(cstring_to_text_with_len(buffer, + snippetLength)); + } + pfree(buffer); + + dims[0] = nResults; + lbs[0] = 1; + + *snippetArray = construct_md_array(snippets, NULL, + 1, dims, lbs, + TEXTOID, -1, false, 'i'); + return GRN_SUCCESS; +} + +/** + * pgroonga.snippet_html(target text, keywords text[]) : text[] + */ +Datum +pgroonga_snippet_html(PG_FUNCTION_ARGS) +{ + text *target = PG_GETARG_TEXT_PP(0); + ArrayType *keywords = PG_GETARG_ARRAYTYPE_P(1); + grn_obj *snip; + grn_rc rc; + ArrayType *snippets; + + snip = PGrnSnipCreate(keywords); + rc = PGrnSnipExec(snip, target, &snippets); + grn_obj_close(ctx, snip); + + if (rc != GRN_SUCCESS) { + ereport(ERROR, + (errcode(PGrnRCToPgErrorCode(rc)), + errmsg("pgroonga: failed to compute snippets"))); + } + + PG_RETURN_POINTER(snippets); +} Modified: src/pgroonga.c (+0 -129) =================================================================== --- src/pgroonga.c 2016-04-23 15:32:40 +0900 (bd0b5c9) +++ src/pgroonga.c 2016-04-23 15:41:07 +0900 (abba946) @@ -1118,135 +1118,6 @@ pgroonga_command(PG_FUNCTION_ARGS) PG_RETURN_TEXT_P(result); } -static grn_obj * -PGrnSnipCreate(ArrayType *keywords) -{ - grn_obj *snip; - int flags = GRN_SNIP_SKIP_LEADING_SPACES; - unsigned int width = 200; - unsigned int maxNResults = 3; - const char *openTag = "<span class=\"keyword\">"; - const char *closeTag = "</span>"; - grn_snip_mapping *mapping = GRN_SNIP_MAPPING_HTML_ESCAPE; - - snip = grn_snip_open(ctx, flags, width, maxNResults, - openTag, strlen(openTag), - closeTag, strlen(closeTag), - mapping); - if (!snip) - { - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("pgroonga: " - "failed to allocate memory for generating snippet"))); - return NULL; - } - - grn_snip_set_normalizer(ctx, snip, GRN_NORMALIZER_AUTO); - - { - int i, n; - - n = ARR_DIMS(keywords)[0]; - for (i = 1; i <= n; i++) - { - Datum keywordDatum; - text *keyword; - bool isNULL; - - keywordDatum = array_ref(keywords, 1, &i, -1, -1, false, - 'i', &isNULL); - if (isNULL) - continue; - - keyword = DatumGetTextPP(keywordDatum); - grn_snip_add_cond(ctx, snip, - VARDATA_ANY(keyword), - VARSIZE_ANY_EXHDR(keyword), - NULL, 0, NULL, 0); - } - } - - return snip; -} - -static grn_rc -PGrnSnipExec(grn_obj *snip, text *target, ArrayType **snippetArray) -{ - grn_rc rc; - unsigned int i, nResults, maxTaggedLength; - char *buffer; - Datum *snippets; - int dims[1]; - int lbs[1]; - - rc = grn_snip_exec(ctx, snip, - VARDATA_ANY(target), - VARSIZE_ANY_EXHDR(target), - &nResults, &maxTaggedLength); - if (rc != GRN_SUCCESS) - { - return rc; - } - - if (nResults == 0) - { - *snippetArray = construct_empty_array(TEXTOID); - return GRN_SUCCESS; - } - - buffer = palloc(sizeof(char) * maxTaggedLength); - snippets = palloc(sizeof(Datum) * nResults); - for (i = 0; i < nResults; i++) - { - grn_rc rc; - unsigned int snippetLength = 0; - - rc = grn_snip_get_result(ctx, snip, i, buffer, &snippetLength); - if (rc != GRN_SUCCESS) - { - pfree(buffer); - return rc; - } - snippets[i] = PointerGetDatum(cstring_to_text_with_len(buffer, - snippetLength)); - } - pfree(buffer); - - dims[0] = nResults; - lbs[0] = 1; - - *snippetArray = construct_md_array(snippets, NULL, - 1, dims, lbs, - TEXTOID, -1, false, 'i'); - return GRN_SUCCESS; -} - -/** - * pgroonga.snippet_html(target text, keywords text[]) : text[] - */ -Datum -pgroonga_snippet_html(PG_FUNCTION_ARGS) -{ - text *target = PG_GETARG_TEXT_PP(0); - ArrayType *keywords = PG_GETARG_ARRAYTYPE_P(1); - grn_obj *snip; - grn_rc rc; - ArrayType *snippets; - - snip = PGrnSnipCreate(keywords); - rc = PGrnSnipExec(snip, target, &snippets); - grn_obj_close(ctx, snip); - - if (rc != GRN_SUCCESS) { - ereport(ERROR, - (errcode(PGrnRCToPgErrorCode(rc)), - errmsg("pgroonga: failed to compute snippets"))); - } - - PG_RETURN_POINTER(snippets); -} - static grn_bool pgroonga_match_term_raw(const char *text, unsigned int textSize, const char *term, unsigned int termSize) -------------- next part -------------- HTML����������������������������...Télécharger