Thread

  1. PQprintf

    Adam Siegel <adam@sycamorehq.com> — 2002-03-01T13:45:22Z

    I have developed a function to help me with escaping strings more easily.  
    It kind of behaves like printf and is very crude.  Before I do anymore
    work, I was hoping to get some comments or notice if someone has already
    done this.
    
    I was also thinking there could be a function call PQprintfExec that would
    build the sql from the printf and call PQexec in one step.
    
    Comments Please!
    
    Regards, 
    Adam
    
    
    /*
     * PQprintf
     *
     * This function acts kind of like printf.  It takes care of escaping
     * strings and bytea for you, then runs PQexec.  The format string
     * defintion is as follows:
     *
     *   %i = integer
     *   %f = float
     *   %s = normal string
     *   %e = escape the string
     *   %b = escape the bytea
     * 
     * When you use %b, you must add another argument just after the
     * variable holding the binary data with its length.
     *
     */
    char *
    PQprintf(const char *format, ...)
    {
         va_list arg;
         char *sql = NULL;
         char *parse = (char*)strdup(format);
         char *p;
         char buff[256];
         char *str;
         char *to;
         size_t length;
         size_t size;
         size_t esize;
         char* s_arg;
         float f_arg;
         int i_arg;
         int i;
    
         va_start(arg, format);
    
         p = (char*)strtok(parse, "%");
         sql = (char*)strdup(p);
         size = strlen(sql);
    
         while (p)
         {
    	  if ((p = (char*)strtok(NULL, "%")))
    	  {
    	       switch (*p) 
    	       {
    		    /* integer */
    	       case 'i':
    		    i_arg = va_arg(arg, int);
    		    sprintf(buff, "%i", i_arg);
    		    size += strlen(buff);
    		    sql = (char*)realloc(sql, size + 1);
    		    strcat(sql, buff);
    		    break;
    
    		    /* float */
    	       case 'f':
    		    f_arg = va_arg(arg, float);
    		    sprintf(buff, "%f", f_arg);
    		    size += strlen(buff);
    		    sql = (char*)realloc(sql, size + 1);
    		    strcat(sql, buff);
    		    break;
    
    		    /* string */
    	       case 's':
    		    s_arg = va_arg(arg, char*);
    		    puts(s_arg);
    		    size += strlen(s_arg);
    		    sql = (char*)realloc(sql, size + 1);
    		    strcat(sql, s_arg);
    		    break;
    
    		    /* escape string */
    	       case 'e':
    		    s_arg = va_arg(arg, char*);
    		    to = (char*)malloc((2 * strlen(s_arg)) + 1);
    		    PQescapeString(to, s_arg, strlen(s_arg));
    		    size += strlen(to);
    		    sql = (char*)realloc(sql, size + 1);
    		    strcat(sql, to);
    		    free(to);
    		    break;
    
    		    /* escape bytea */
    	       case 'b':
    		    s_arg = va_arg(arg, char*);
    		    length = va_arg(arg, int);
    		    str = PQescapeBytea(s_arg, length, &esize);
    		    size += esize;
    		    sql = (char*)realloc(sql, size + 1);
    		    strcat(sql, str);
    		    free(str);
    		    break;
    	       }
    
    	       size += strlen(++p);
    	       sql = (char*)realloc(sql, size + 1);
    	       strcat(sql, p);
    	  }
         }
    
         va_end(arg);
    
         free(parse);
    
         return sql;
    }
    
    
    
    
    
    
  2. Re: PQprintf

    Tom Lane <tgl@sss.pgh.pa.us> — 2002-03-01T15:25:13Z

    Adam Siegel <adam@sycamorehq.com> writes:
    > I have developed a function to help me with escaping strings more easily.  
    > It kind of behaves like printf and is very crude.  Before I do anymore
    > work, I was hoping to get some comments or notice if someone has already
    > done this.
    
    Seems like the start of a good idea, though I agree it's crude yet.
    One thing you definitely need is more control over %f (precision
    arguments).
    
    One suggestion: use libpq's "pqexpbuffer.h" routines to manipulate the
    expansible string buffer, instead of reinventing that wheel yet again.
    
    			regards, tom lane