libdrizzle Developer Documentation

examples/server.c
Go to the documentation of this file.
00001 /*
00002  * Drizzle Client & Protocol Library
00003  *
00004  * Copyright (C) 2008 Eric Day (eday@oddments.org)
00005  * All rights reserved.
00006  *
00007  * Use and distribution licensed under the BSD license.  See
00008  * the COPYING file in this directory for full text.
00009  */
00010 
00011 #include <errno.h>
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <unistd.h>
00015 
00016 #include <libdrizzle/drizzle_server.h>
00017 
00018 #define DRIZZLE_FIELD_MAX 32
00019 #define DRIZZLE_RESULT_ROWS 20
00020 
00021 #define DRIZZLE_RETURN_CHECK(__ret, __function, __drizzle) \
00022 { \
00023   if ((__ret) != DRIZZLE_RETURN_OK) \
00024     DRIZZLE_RETURN_ERROR(__function, __drizzle) \
00025 }
00026 
00027 #define DRIZZLE_RETURN_ERROR(__function, __drizzle) \
00028 { \
00029   printf(__function ":%s\n", drizzle_error(__drizzle)); \
00030   return; \
00031 }
00032 
00033 static void server(drizzle_st *drizzle, drizzle_con_st *con,
00034                    drizzle_result_st *result, drizzle_column_st *column);
00035 
00036 int main(int argc, char *argv[])
00037 {
00038   int c;
00039   uint32_t count= 0;
00040   const char *host= NULL;
00041   bool mysql= false;
00042   in_port_t port= 0;
00043   drizzle_verbose_t verbose= DRIZZLE_VERBOSE_NEVER;
00044   drizzle_return_t ret;
00045   drizzle_st drizzle;
00046   drizzle_con_st con_listen;
00047   drizzle_con_st con;
00048   drizzle_result_st result;
00049   drizzle_column_st column;
00050 
00051   while((c = getopt(argc, argv, "c:h:mp:v")) != -1)
00052   {
00053     switch(c)
00054     {
00055     case 'c':
00056       count= (uint32_t)atoi(optarg);
00057       break;
00058 
00059     case 'h':
00060       host= optarg;
00061       break;
00062 
00063     case 'm':
00064       mysql= true;
00065       break;
00066 
00067     case 'p':
00068       port= (in_port_t)atoi(optarg);
00069       break;
00070 
00071     case 'v':
00072       verbose++;
00073       break;
00074 
00075     default:
00076       printf("\nusage: %s [-c <count>] [-h <host>] [-m] [-p <port>] [-v]\n",
00077              argv[0]);
00078       printf("\t-c <count> - Number of connections to accept before exiting\n");
00079       printf("\t-h <host>  - Host to listen on\n");
00080       printf("\t-m         - Use the MySQL protocol\n");
00081       printf("\t-p <port>  - Port to listen on\n");
00082       printf("\t-v         - Increase verbosity level\n");
00083       return 1;
00084     }
00085   }
00086 
00087   if (drizzle_create(&drizzle) == NULL)
00088   {
00089     printf("drizzle_create:NULL\n");
00090     return 1;
00091   }
00092 
00093   drizzle_add_options(&drizzle, DRIZZLE_FREE_OBJECTS);
00094   drizzle_set_verbose(&drizzle, verbose);
00095 
00096   if (drizzle_con_create(&drizzle, &con_listen) == NULL)
00097   {
00098     printf("drizzle_con_create:NULL\n");
00099     return 1;
00100   }
00101 
00102   drizzle_con_add_options(&con_listen, DRIZZLE_CON_LISTEN);
00103   drizzle_con_set_tcp(&con_listen, host, port);
00104 
00105   if (mysql)
00106     drizzle_con_add_options(&con_listen, DRIZZLE_CON_MYSQL);
00107 
00108   if (drizzle_con_listen(&con_listen) != DRIZZLE_RETURN_OK)
00109   {
00110     printf("drizzle_con_listen:%s\n", drizzle_error(&drizzle));
00111     return 1;
00112   }
00113 
00114   while (1)
00115   {
00116     (void)drizzle_con_accept(&drizzle, &con, &ret);
00117     if (ret != DRIZZLE_RETURN_OK)
00118     {
00119       printf("drizzle_con_accept:%s\n", drizzle_error(&drizzle));
00120       return 1;
00121     }
00122 
00123     server(&drizzle, &con, &result, &column);
00124 
00125     drizzle_con_free(&con);
00126 
00127     if (count > 0)
00128     {
00129       count--;
00130 
00131       if (count == 0)
00132         break;
00133     }
00134   }
00135 
00136   drizzle_con_free(&con_listen);
00137   drizzle_free(&drizzle);
00138 
00139   return 0;
00140 }
00141 
00142 static void server(drizzle_st *drizzle, drizzle_con_st *con,
00143                    drizzle_result_st *result, drizzle_column_st *column)
00144 {
00145   drizzle_return_t ret;
00146   drizzle_command_t command;
00147   uint8_t *data= NULL;
00148   size_t total;
00149   char *field[2];
00150   char field1[DRIZZLE_FIELD_MAX];
00151   char field2[DRIZZLE_FIELD_MAX];
00152   size_t size[2];
00153   uint64_t x;
00154 
00155   field[0]= field1;
00156   field[1]= field2;
00157 
00158   /* Handshake packets. */
00159   drizzle_con_set_protocol_version(con, 10);
00160   drizzle_con_set_server_version(con, "libdrizzle example 1.2.3");
00161   drizzle_con_set_thread_id(con, 1);
00162   drizzle_con_set_scramble(con, (const uint8_t *)"ABCDEFGHIJKLMNOPQRST");
00163   drizzle_con_set_capabilities(con, DRIZZLE_CAPABILITIES_NONE);
00164   drizzle_con_set_charset(con, 8);
00165   drizzle_con_set_status(con, DRIZZLE_CON_STATUS_NONE);
00166   drizzle_con_set_max_packet_size(con, DRIZZLE_MAX_PACKET_SIZE);
00167 
00168   ret= drizzle_handshake_server_write(con);
00169   DRIZZLE_RETURN_CHECK(ret, "drizzle_handshake_server_write", drizzle)
00170 
00171   ret= drizzle_handshake_client_read(con);
00172   DRIZZLE_RETURN_CHECK(ret, "drizzle_handshake_client_read", drizzle)
00173 
00174   if (drizzle_result_create(con, result) == NULL)
00175     DRIZZLE_RETURN_ERROR("drizzle_result_create", drizzle)
00176 
00177   ret= drizzle_result_write(con, result, true);
00178   DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
00179 
00180   /* Command loop. */
00181   while (1)
00182   {
00183     drizzle_result_free(result);
00184     if (data != NULL)
00185       free(data);
00186 
00187     data= drizzle_con_command_buffer(con, &command, &total, &ret);
00188     if (ret == DRIZZLE_RETURN_LOST_CONNECTION ||
00189         (ret == DRIZZLE_RETURN_OK && command == DRIZZLE_COMMAND_QUIT))
00190     {
00191       if (data != NULL)
00192         free(data);
00193       return;
00194     }
00195     DRIZZLE_RETURN_CHECK(ret, "drizzle_con_command_buffer", drizzle)
00196 
00197     if (drizzle_result_create(con, result) == NULL)
00198       DRIZZLE_RETURN_ERROR("drizzle_result_create", drizzle)
00199 
00200     if (command != DRIZZLE_COMMAND_QUERY)
00201     {
00202       ret= drizzle_result_write(con, result, true);
00203       DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
00204       continue;
00205     }
00206 
00207     drizzle_result_set_column_count(result, 2);
00208 
00209     ret= drizzle_result_write(con, result, false);
00210     DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
00211 
00212     /* Columns. */
00213     if (drizzle_column_create(result, column) == NULL)
00214       DRIZZLE_RETURN_ERROR("drizzle_column_create", drizzle)
00215 
00216     drizzle_column_set_catalog(column, "default");
00217     drizzle_column_set_db(column, "drizzle_test_db");
00218     drizzle_column_set_table(column, "drizzle_test_table");
00219     drizzle_column_set_orig_table(column, "drizzle_test_table");
00220     drizzle_column_set_name(column, "test_column_1");
00221     drizzle_column_set_orig_name(column, "test_column_1");
00222     drizzle_column_set_charset(column, 8);
00223     drizzle_column_set_size(column, DRIZZLE_FIELD_MAX);
00224     drizzle_column_set_type(column, DRIZZLE_COLUMN_TYPE_VARCHAR);
00225 
00226     ret= drizzle_column_write(result, column);
00227     DRIZZLE_RETURN_CHECK(ret, "drizzle_column_write", drizzle)
00228 
00229     drizzle_column_set_name(column, "test_column_2");
00230     drizzle_column_set_orig_name(column, "test_column_2");
00231 
00232     ret= drizzle_column_write(result, column);
00233     DRIZZLE_RETURN_CHECK(ret, "drizzle_column_write", drizzle)
00234 
00235     drizzle_column_free(column);
00236 
00237     drizzle_result_set_eof(result, true);
00238 
00239     ret= drizzle_result_write(con, result, false);
00240     DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
00241 
00242     /* Rows. */
00243     for (x= 0; x < DRIZZLE_RESULT_ROWS; x++)
00244     {
00245       size[0]= (size_t)snprintf(field[0], DRIZZLE_FIELD_MAX,
00246                                 "field %" PRIu64 "-1", x);
00247       if (size[0] >= DRIZZLE_FIELD_MAX)
00248         size[0]= DRIZZLE_FIELD_MAX - 1;
00249 
00250       size[1]= (size_t)snprintf(field[1], DRIZZLE_FIELD_MAX,
00251                                 "field %" PRIu64 "-2", x);
00252       if (size[1] >= DRIZZLE_FIELD_MAX)
00253         size[1]= DRIZZLE_FIELD_MAX - 1;
00254 
00255       /* This is needed for MySQL and old Drizzle protocol. */
00256       drizzle_result_calc_row_size(result, (drizzle_field_t *)field, size);
00257 
00258       ret= drizzle_row_write(result);
00259       DRIZZLE_RETURN_CHECK(ret, "drizzle_row_write", drizzle)
00260 
00261       /* Fields. */
00262       ret= drizzle_field_write(result, (drizzle_field_t)field[0], size[0],
00263                                size[0]);
00264       DRIZZLE_RETURN_CHECK(ret, "drizzle_field_write", drizzle)
00265 
00266       ret= drizzle_field_write(result, (drizzle_field_t)field[1], size[1],
00267                                size[1]);
00268       DRIZZLE_RETURN_CHECK(ret, "drizzle_field_write", drizzle)
00269     }
00270 
00271     ret= drizzle_result_write(con, result, true);
00272     DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
00273   }
00274 }