/* -*- Mode: C; fill-column: 79 -*- ******************************************* ******************************************************************************* unprefix.c Time-stamp: <1998-08-10 19:47:13 awk@oxygene.vnet.net> by Alexander Kourakos <Alexander@Kourakos.com>
This UDF for mySQL strips one article off the front of a string, for example, ``The Grapes of Wrath'' -> ``Grapes of Wrath''.
It was originally designed for a music database. Sometimes musical artists put ``The'' in front of their names, sometimes not. With this function, you could do something like: SELECT DISTINCT unprefix(ArtistName) FROM db ORDER BY 1 or SELECT Title,ArtistName,unprefix(ArtistName) FROM db ORDER BY 3,1 and just use the first two columns in your application.
After a while, using the mySQL built-ins was too messy so I wrote this function. I hope someone finds it useful! ******************************************************************************* ******************************************************************************/
#include <global.h> #include <my_sys.h> #include <mysql.h> #include <m_string.h> #include <m_ctype.h>
typedef struct ignorestruct { size_t l; char *s; } ignorestruct;
/* * The table currently contains English and French articles. */
static const ignorestruct ignore[] = { { 2, "a " }, { 3, "an " }, { 4, "the " }, { 3, "la " }, { 3, "le " }, { 2, "l'" }, { 0, NULL } };
my_bool unprefix_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void unprefix_deinit(UDF_INIT *); char *unprefix(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);
my_bool unprefix_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT) { strmov(message, "Wrong argument(s) to unprefix(STRING)."); return 1; } return 0; }
void unprefix_deinit(UDF_INIT *initid) { }
char *unprefix(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error) { char *the_str = args->args[0]; unsigned long the_len = args->lengths[0]; const ignorestruct *p;
if (!the_str) { *is_null = 1; return NULL; }
for (p = ignore; p->l > 0; ++p) if (!strncasecmp(p->s, the_str, p->l)) { the_str += p->l; the_len -= p->l; break; }
*length = the_len; strncpy(result, the_str, the_len); return result; }
/****************************************************************************** END OF FILE ******************************************************************************/
|