<commit_before>/* This file is part of the YAZ toolkit.
 * Copyright (C) 1995-2011 Index Data
 * See the file LICENSE for details.
 */
/**
 * \file
 * \brief Implements RPN to SOLR conversion
 */
#if HAVE_CONFIG_H
#include <config.h>
#endif

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <yaz/rpn2solr.h>
#include <yaz/xmalloc.h>
#include <yaz/diagbib1.h>
#include <yaz/z-core.h>
#include <yaz/wrbuf.h>

static void wrbuf_vputs(const char *buf, void *client_data)
{
    wrbuf_write((WRBUF) client_data, buf, strlen(buf));
}

static const char *lookup_index_from_string_attr(Z_AttributeList *attributes)
{
    int j;
    int server_choice = 1;
    for (j = 0; j < attributes->num_attributes; j++)
    {
        Z_AttributeElement *ae = attributes->attributes[j];
        if (*ae->attributeType == 1) /* use attribute */
        {
            if (ae->which == Z_AttributeValue_complex)
            {
                Z_ComplexAttribute *ca = ae->value.complex;
                int i;
                for (i = 0; i < ca->num_list; i++)
                {
                    Z_StringOrNumeric *son = ca->list[i];
                    if (son->which == Z_StringOrNumeric_string)
                        return son->u.string;
                }
            }
            server_choice = 0; /* not serverChoice because we have use attr */
        }
    }
    if (server_choice)
        return "solr.serverChoice";
    return 0;
}

static const char *lookup_relation_index_from_attr(Z_AttributeList *attributes)
{
    int j;
    for (j = 0; j < attributes->num_attributes; j++)
    {
        Z_AttributeElement *ae = attributes->attributes[j];
        if (*ae->attributeType == 2) /* relation attribute */
        {
            if (ae->which == Z_AttributeValue_numeric)
            {
                /* Only support for numeric relation */
                Odr_int *relation = ae->value.numeric;
                /* map this numeric to representation in SOLR */
                switch (*relation)
                {
                    /* Unsure on whether this is the relation attribute constants? */
                case Z_ProximityOperator_Prox_lessThan: 
                    return 0;
                case Z_ProximityOperator_Prox_lessThanOrEqual: 
                    return 0;
                case Z_ProximityOperator_Prox_equal: 
                    return ":";
                case Z_ProximityOperator_Prox_greaterThanOrEqual: 
                    return 0;
                case Z_ProximityOperator_Prox_greaterThan: 
                    return 0;
                case Z_ProximityOperator_Prox_notEqual: 
                    return 0;
                case 100: 
                    /* phonetic is not implemented*/
                    return 0; 
                case 101: 
                    /* stem is not not implemented */
                    return 0; 
                case 102: 
                    /* relevance is supported in SOLR, but not implemented yet */
                    return 0; 
                default:
                    /* Invalid relation */
                    return 0;
                }
            }
            else {
                /*  Can we have a complex relation value?
                    Should we implement something?
                */
            }
        }
    }
    return ":";
}

static int rpn2solr_attr(solr_transform_t ct,
                        Z_AttributeList *attributes, WRBUF w)
{
    const char *relation = solr_lookup_reverse(ct, "relation.", attributes);
    const char *index = solr_lookup_reverse(ct, "index.", attributes);
    const char *structure = solr_lookup_reverse(ct, "structure.", attributes);

    /* if transform (properties) do not match, we'll just use a USE string attribute (bug #2978) */
    if (!index)
        index = lookup_index_from_string_attr(attributes);

    /* Attempt to fix bug #2978: Look for a relation attribute */
    if (!relation) 
        relation = lookup_relation_index_from_attr(attributes);

    if (!index)
    {
        solr_transform_set_error(ct,
                                YAZ_BIB1_UNSUPP_USE_ATTRIBUTE, 0);
        return -1;
    }
    /* for serverChoice we omit index+relation+structure */
    if (strcmp(index, "solr.serverChoice"))
    {
        wrbuf_puts(w, index);
        if (relation)
        {
            if (!strcmp(relation, "exact"))
                /* TODO Verify if a exact  SOLR exists */
                relation = ":";
            else if (!strcmp(relation, "eq"))
                relation = ":";
            else if (!strcmp(relation, "le")) {
                /* TODO Not support as such, but could perhaps be transformed into a range
                relation = ":[ * to ";
                close_range = "]"
                */
            }
            else if (!strcmp(relation, "ge")) {
                /* TODO Not support as such, but could perhaps be transformed into a range
                relation = "[";
                relation = ":[ * to ";
                close_range = "]"
                */
            }
            /* Missing mapping of not equal, phonetic, stem and relevance */
            wrbuf_puts(w, relation);
        }
        else
            wrbuf_puts(w, ":");

        if (structure)
        {
            if (strcmp(structure, "*"))
            {
                wrbuf_puts(w, "/");
                wrbuf_puts(w, structure);
                wrbuf_puts(w, " ");
            }
        }
    }
    return 0;
}

/* Bug 2878: Currently only support left and right truncation. Specific check for this */
static int checkForTruncation(int flag, Z_AttributeList *attributes)
{
    int j;
    for (j = 0; j < attributes->num_attributes; j++)
    {
        Z_AttributeElement *ae = attributes->attributes[j];
        if (*ae->attributeType == 5) /* truncation attribute */
        {
            if (ae->which == Z_AttributeValue_numeric)
            {
                Odr_int truncation = *(ae->value.numeric);
                /* This logic only works for Left, right and both. eg. 1,2,3 */
            	if (truncation <= 3)
                    return ((int) truncation & flag);
            }
            /* Complex: Shouldn't happen */
        }
    }
    /* No truncation or unsupported */
    return 0;
};

static int checkForLeftTruncation(Z_AttributeList *attributes) {
	return checkForTruncation(1, attributes);
}

static int checkForRightTruncation(Z_AttributeList *attributes) {
	return checkForTruncation(2, attributes);
};
<commit_msg>Fix left/right switch of truncation flag<commit_after>/* This file is part of the YAZ toolkit.
 * Copyright (C) 1995-2011 Index Data
 * See the file LICENSE for details.
 */
/**
 * \file
 * \brief Implements RPN to SOLR conversion
 */
#if HAVE_CONFIG_H
#include <config.h>
#endif

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <yaz/rpn2solr.h>
#include <yaz/xmalloc.h>
#include <yaz/diagbib1.h>
#include <yaz/z-core.h>
#include <yaz/wrbuf.h>

static void wrbuf_vputs(const char *buf, void *client_data)
{
    wrbuf_write((WRBUF) client_data, buf, strlen(buf));
}

static const char *lookup_index_from_string_attr(Z_AttributeList *attributes)
{
    int j;
    int server_choice = 1;
    for (j = 0; j < attributes->num_attributes; j++)
    {
        Z_AttributeElement *ae = attributes->attributes[j];
        if (*ae->attributeType == 1) /* use attribute */
        {
            if (ae->which == Z_AttributeValue_complex)
            {
                Z_ComplexAttribute *ca = ae->value.complex;
                int i;
                for (i = 0; i < ca->num_list; i++)
                {
                    Z_StringOrNumeric *son = ca->list[i];
                    if (son->which == Z_StringOrNumeric_string)
                        return son->u.string;
                }
            }
            server_choice = 0; /* not serverChoice because we have use attr */
        }
    }
    if (server_choice)
        return "solr.serverChoice";
    return 0;
}

static const char *lookup_relation_index_from_attr(Z_AttributeList *attributes)
{
    int j;
    for (j = 0; j < attributes->num_attributes; j++)
    {
        Z_AttributeElement *ae = attributes->attributes[j];
        if (*ae->attributeType == 2) /* relation attribute */
        {
            if (ae->which == Z_AttributeValue_numeric)
            {
                /* Only support for numeric relation */
                Odr_int *relation = ae->value.numeric;
                /* map this numeric to representation in SOLR */
                switch (*relation)
                {
                    /* Unsure on whether this is the relation attribute constants? */
                case Z_ProximityOperator_Prox_lessThan: 
                    return 0;
                case Z_ProximityOperator_Prox_lessThanOrEqual: 
                    return 0;
                case Z_ProximityOperator_Prox_equal: 
                    return ":";
                case Z_ProximityOperator_Prox_greaterThanOrEqual: 
                    return 0;
                case Z_ProximityOperator_Prox_greaterThan: 
                    return 0;
                case Z_ProximityOperator_Prox_notEqual: 
                    return 0;
                case 100: 
                    /* phonetic is not implemented*/
                    return 0; 
                case 101: 
                    /* stem is not not implemented */
                    return 0; 
                case 102: 
                    /* relevance is supported in SOLR, but not implemented yet */
                    return 0; 
                default:
                    /* Invalid relation */
                    return 0;
                }
            }
            else {
                /*  Can we have a complex relation value?
                    Should we implement something?
                */
            }
        }
    }
    return ":";
}

static int rpn2solr_attr(solr_transform_t ct,
                        Z_AttributeList *attributes, WRBUF w)
{
    const char *relation = solr_lookup_reverse(ct, "relation.", attributes);
    const char *index = solr_lookup_reverse(ct, "index.", attributes);
    const char *structure = solr_lookup_reverse(ct, "structure.", attributes);

    /* if transform (properties) do not match, we'll just use a USE string attribute (bug #2978) */
    if (!index)
        index = lookup_index_from_string_attr(attributes);

    /* Attempt to fix bug #2978: Look for a relation attribute */
    if (!relation) 
        relation = lookup_relation_index_from_attr(attributes);

    if (!index)
    {
        solr_transform_set_error(ct,
                                YAZ_BIB1_UNSUPP_USE_ATTRIBUTE, 0);
        return -1;
    }
    /* for serverChoice we omit index+relation+structure */
    if (strcmp(index, "solr.serverChoice"))
    {
        wrbuf_puts(w, index);
        if (relation)
        {
            if (!strcmp(relation, "exact"))
                /* TODO Verify if a exact  SOLR exists */
                relation = ":";
            else if (!strcmp(relation, "eq"))
                relation = ":";
            else if (!strcmp(relation, "le")) {
                /* TODO Not support as such, but could perhaps be transformed into a range
                relation = ":[ * to ";
                close_range = "]"
                */
            }
            else if (!strcmp(relation, "ge")) {
                /* TODO Not support as such, but could perhaps be transformed into a range
                relation = "[";
                relation = ":[ * to ";
                close_range = "]"
                */
            }
            /* Missing mapping of not equal, phonetic, stem and relevance */
            wrbuf_puts(w, relation);
        }
        else
            wrbuf_puts(w, ":");

        if (structure)
        {
            if (strcmp(structure, "*"))
            {
                wrbuf_puts(w, "/");
                wrbuf_puts(w, structure);
                wrbuf_puts(w, " ");
            }
        }
    }
    return 0;
}

/* Bug 2878: Currently only support left and right truncation. Specific check for this */
static int checkForTruncation(int flag, Z_AttributeList *attributes)
{
    int j;
    for (j = 0; j < attributes->num_attributes; j++)
    {
        Z_AttributeElement *ae = attributes->attributes[j];
        if (*ae->attributeType == 5) /* truncation attribute */
        {
            if (ae->which == Z_AttributeValue_numeric)
            {
                Odr_int truncation = *(ae->value.numeric);
                /* This logic only works for Left, right and both. eg. 1,2,3 */
            	if (truncation <= 3)
                    return ((int) truncation & flag);
            }
            else if (ae->which == Z_AttributeValue_complex) {
                //yaz_log(YLOG_DEBUG, "Z_Attribute_complex");
                /* Complex: Shouldn't happen */
            }
        }
    }
    /* No truncation or unsupported */
    return 0;
};

static int checkForLeftTruncation(Z_AttributeList *attributes) {
	return checkForTruncation(2, attributes);
}

static int checkForRightTruncation(Z_AttributeList *attributes) {
	return checkForTruncation(1, attributes);
};

{'fraction_non_alphanumeric': 0.10062940775005687, 'fraction_numerical': 0.009403200121331614, 'mean_word_length': 1.5762844305528423, 'pattern_counts': {'":': 14, '<': 31, '<?xml version=': 0, '>': 60, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1147749', 'n_tokens_mistral': 3837, 'n_tokens_neox': 3533, 'n_words': 973}