Advertisement
Guest User

Untitled

a guest
Mar 20th, 2022
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.30 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #include "defines.h"
  6.  
  7. void print_stmt_error (MYSQL_STMT *stmt, char *message)
  8. {
  9.     fprintf (stderr, "%s\n", message);
  10.     if (stmt != NULL) {
  11.         fprintf (stderr, "Error %u (%s): %s\n",
  12.             mysql_stmt_errno (stmt),
  13.             mysql_stmt_sqlstate(stmt),
  14.             mysql_stmt_error (stmt));
  15.     }
  16. }
  17.  
  18.  
  19. void print_error(MYSQL *conn, char *message)
  20. {
  21.     fprintf (stderr, "%s\n", message);
  22.     if (conn != NULL) {
  23.         #if MYSQL_VERSION_ID >= 40101
  24.         fprintf (stderr, "Error %u (%s): %s\n",
  25.         mysql_errno (conn), mysql_sqlstate(conn), mysql_error (conn));
  26.         #else
  27.         fprintf (stderr, "Error %u: %s\n",
  28.         mysql_errno (conn), mysql_error (conn));
  29.         #endif
  30.     }
  31. }
  32.  
  33. bool setup_prepared_stmt(MYSQL_STMT **stmt, char *statement, MYSQL *conn)
  34. {
  35.     my_bool update_length = true;
  36.  
  37.     *stmt = mysql_stmt_init(conn);
  38.     if (*stmt == NULL)
  39.     {
  40.         print_error(conn, "Could not initialize statement handler");
  41.         return false;
  42.     }
  43.  
  44.     if (mysql_stmt_prepare (*stmt, statement, strlen(statement)) != 0) {
  45.         print_stmt_error(*stmt, "Could not prepare statement");
  46.         return false;
  47.     }
  48.  
  49.     mysql_stmt_attr_set(*stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &update_length);
  50.  
  51.     return true;
  52. }
  53.  
  54. void finish_with_error(MYSQL *conn, char *message)
  55. {
  56.     print_error(conn, message);
  57.     mysql_close(conn);
  58.     exit(EXIT_FAILURE);        
  59. }
  60.  
  61. void finish_with_stmt_error(MYSQL *conn, MYSQL_STMT *stmt, char *message, bool close_stmt)
  62. {
  63.     print_stmt_error(stmt, message);
  64.     if(close_stmt)  mysql_stmt_close(stmt);
  65.     mysql_close(conn);
  66.     exit(EXIT_FAILURE);        
  67. }
  68.  
  69. static void print_dashes(MYSQL_RES *res_set)
  70. {
  71.     MYSQL_FIELD *field;
  72.     unsigned int i, j;
  73.  
  74.     mysql_field_seek(res_set, 0);
  75.     putchar('+');
  76.     for (i = 0; i < mysql_num_fields(res_set); i++) {
  77.         field = mysql_fetch_field(res_set);
  78.         for (j = 0; j < field->max_length + 2; j++)
  79.             putchar('-');
  80.         putchar('+');
  81.     }
  82.     putchar('\n');
  83. }
  84.  
  85. static void dump_result_set_header(MYSQL_RES *res_set)
  86. {
  87.     MYSQL_FIELD *field;
  88.     unsigned long col_len;
  89.     unsigned int i;
  90.  
  91.     /* determine column display widths -- requires result set to be */
  92.     /* generated with mysql_store_result(), not mysql_use_result() */
  93.  
  94.     mysql_field_seek (res_set, 0);
  95.  
  96.     for (i = 0; i < mysql_num_fields (res_set); i++) {
  97.         field = mysql_fetch_field (res_set);
  98.         col_len = strlen(field->name);
  99.  
  100.         if (col_len < field->max_length)
  101.             col_len = field->max_length;
  102.         if (col_len < 4 && !IS_NOT_NULL(field->flags))
  103.             col_len = 4; /* 4 = length of the word "NULL" */
  104.         field->max_length = col_len; /* reset column info */
  105.     }
  106.    
  107.     print_dashes(res_set);
  108.     putchar('|');
  109.     mysql_field_seek (res_set, 0);
  110.     for (i = 0; i < mysql_num_fields(res_set); i++) {
  111.         field = mysql_fetch_field(res_set);
  112.         printf(" %-*s |", (int)field->max_length, field->name);
  113.     }
  114.     putchar('\n');
  115.  
  116.     print_dashes(res_set);
  117. }
  118.  
  119. void dump_result_set(MYSQL *conn, MYSQL_STMT *stmt, char *title)
  120. {
  121.     int i;
  122.     int status;
  123.     int num_fields;       /* number of columns in result */
  124.     MYSQL_FIELD *fields;  /* for result set metadata */
  125.     MYSQL_BIND *rs_bind;  /* for output buffers */
  126.     MYSQL_RES *rs_metadata;
  127.     MYSQL_TIME *date;
  128.     size_t attr_size;
  129.  
  130.     /* Prefetch the whole result set. This in conjunction with
  131.      * STMT_ATTR_UPDATE_MAX_LENGTH set in `setup_prepared_stmt`
  132.      * updates the result set metadata which are fetched in this
  133.      * function, to allow to compute the actual max length of
  134.      * the columns.
  135.      */
  136.     if (mysql_stmt_store_result(stmt)) {
  137.         fprintf(stderr, " mysql_stmt_execute(), 1 failed\n");
  138.         fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  139.         exit(0);
  140.     }      
  141.  
  142.     /* the column count is > 0 if there is a result set */
  143.     /* 0 if the result is only the final status packet */
  144.     num_fields = mysql_stmt_field_count(stmt);
  145.  
  146.     if (num_fields > 0) {
  147.         /* there is a result set to fetch */
  148.         printf("%s\n", title);
  149.  
  150.         if((rs_metadata = mysql_stmt_result_metadata(stmt)) == NULL) {
  151.             finish_with_stmt_error(conn, stmt, "Unable to retrieve result metadata\n", true);
  152.         }
  153.  
  154.         dump_result_set_header(rs_metadata);
  155.        
  156.         fields = mysql_fetch_fields(rs_metadata);
  157.  
  158.         rs_bind = (MYSQL_BIND *)malloc(sizeof (MYSQL_BIND) * num_fields);
  159.         if (!rs_bind) {
  160.             finish_with_stmt_error(conn, stmt, "Cannot allocate output buffers\n", true);
  161.         }
  162.         memset(rs_bind, 0, sizeof (MYSQL_BIND) * num_fields);
  163.  
  164.         /* set up and bind result set output buffers */
  165.         for (i = 0; i < num_fields; ++i) {
  166.  
  167.             // Properly size the parameter buffer
  168.             switch(fields[i].type) {
  169.                 case MYSQL_TYPE_DATE:
  170.                 case MYSQL_TYPE_TIMESTAMP:
  171.                 case MYSQL_TYPE_DATETIME:
  172.                 case MYSQL_TYPE_TIME:
  173.                     attr_size = sizeof(MYSQL_TIME);
  174.                     break;
  175.                 case MYSQL_TYPE_FLOAT:
  176.                     attr_size = sizeof(float);
  177.                     break;
  178.                 case MYSQL_TYPE_DOUBLE:
  179.                     attr_size = sizeof(double);
  180.                     break;
  181.                 case MYSQL_TYPE_TINY:
  182.                     attr_size = sizeof(signed char);
  183.                     break;
  184.                 case MYSQL_TYPE_SHORT:
  185.                 case MYSQL_TYPE_YEAR:
  186.                     attr_size = sizeof(short int);
  187.                     break;
  188.                 case MYSQL_TYPE_LONG:
  189.                 case MYSQL_TYPE_INT24:
  190.                     attr_size = sizeof(int);
  191.                     break;
  192.                 case MYSQL_TYPE_LONGLONG:
  193.                     attr_size = sizeof(int);
  194.                     break;
  195.                 default:
  196.                     attr_size = fields[i].max_length;
  197.                     break;
  198.             }
  199.            
  200.             // Setup the binding for the current parameter
  201.             rs_bind[i].buffer_type = fields[i].type;
  202.             rs_bind[i].buffer = malloc(attr_size + 1);
  203.             rs_bind[i].buffer_length = attr_size + 1;
  204.  
  205.             if(rs_bind[i].buffer == NULL) {
  206.                 finish_with_stmt_error(conn, stmt, "Cannot allocate output buffers\n", true);
  207.             }
  208.         }
  209.  
  210.         if(mysql_stmt_bind_result(stmt, rs_bind)) {
  211.             finish_with_stmt_error(conn, stmt, "Unable to bind output parameters\n", true);
  212.         }
  213.  
  214.         /* fetch and display result set rows */
  215.         while (true) {
  216.             status = mysql_stmt_fetch(stmt);
  217.  
  218.             if (status == 1 || status == MYSQL_NO_DATA)
  219.                 break;
  220.  
  221.             putchar('|');
  222.  
  223.             for (i = 0; i < num_fields; i++) {
  224.  
  225.                 if (rs_bind[i].is_null_value) {
  226.                     printf (" %-*s |", (int)fields[i].max_length, "NULL");
  227.                     continue;
  228.                 }
  229.  
  230.                 switch (rs_bind[i].buffer_type) {
  231.                    
  232.                     case MYSQL_TYPE_VAR_STRING:
  233.                     case MYSQL_TYPE_DATETIME:
  234.                         printf(" %-*s |", (int)fields[i].max_length, (char*)rs_bind[i].buffer);
  235.                         break;
  236.                        
  237.                     case MYSQL_TYPE_DATE:
  238.                     case MYSQL_TYPE_TIMESTAMP:
  239.                         date = (MYSQL_TIME *)rs_bind[i].buffer;
  240.                         printf(" %d-%02d-%02d |", date->year, date->month, date->day);
  241.                         break;
  242.                        
  243.                     case MYSQL_TYPE_STRING:
  244.                         printf(" %-*s |", (int)fields[i].max_length, (char *)rs_bind[i].buffer);
  245.                         break;
  246.          
  247.                     case MYSQL_TYPE_FLOAT:
  248.                     case MYSQL_TYPE_DOUBLE:
  249.                         printf(" %.02f |", *(float *)rs_bind[i].buffer);
  250.                         break;
  251.          
  252.                     case MYSQL_TYPE_LONG:
  253.                     case MYSQL_TYPE_SHORT:
  254.                     case MYSQL_TYPE_TINY:
  255.                         printf(" %-*d |", (int)fields[i].max_length, *(int *)rs_bind[i].buffer);
  256.                         break;
  257.                        
  258.                     case MYSQL_TYPE_NEWDECIMAL:
  259.                         printf(" %-*.02lf |", (int)fields[i].max_length, *(float*) rs_bind[i].buffer);
  260.                         break;
  261.      
  262.                     default:
  263.                         printf("ERROR: Unhandled type (%d)\n", rs_bind[i].buffer_type);
  264.                         abort();
  265.                 }
  266.             }
  267.             putchar('\n');
  268.             print_dashes(rs_metadata);
  269.         }
  270.  
  271.         mysql_free_result(rs_metadata); /* free metadata */
  272.  
  273.         /* free output buffers */
  274.         for (i = 0; i < num_fields; i++) {
  275.             free(rs_bind[i].buffer);
  276.         }
  277.         free(rs_bind);
  278.     }
  279. }
  280.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement