Exemplo n.º 1
0
int main(int argc, const char** argv)
{
  ndb_init();
  const char* usage = "Usage: ndbsql [-h] [-d dsn] [-f file] [stmt]\n-h help\n-d <database name or connect string>\n-f <file name> batch mode\nstmt single SQL statement\n";
  const char* dsn = "TEST_DB";
  bool helpFlg = false, batchMode = false;
  const char* fileName = 0;
  FILE* inputFile = stdin;
  const char* singleStmt = 0;

  s_readBuf = (char*)malloc(s_bufSize);
  while (++argv, --argc > 0) {
    const char* arg = argv[0];
    if (arg[0] != '-')
      break;
    if (strcmp(arg, "-d") == 0) {
      if (++argv, --argc > 0) {
        dsn = argv[0];
        continue;
      }
    }
    if (strcmp(arg, "-h") == 0) {
      helpFlg = true;
      continue;
    }
    if (strcmp(arg, "-f") == 0) {
      if (++argv, --argc > 0) {
	fileName = argv[0];
	continue;
      }
    }
    ndbout << usage;
    return 1;
  }
  if (helpFlg) {
    ndbout << usage << "\n";
    print_help();
    return 0;
  }
  if (fileName != 0) {
    if (argc > 0) {
      ndbout << usage;
      return 1;
    }
    if ((inputFile = fopen(fileName, "r")) == 0) {
      ndbout << "Could not read file " << fileName << ": " << strerror(errno) << endl;
      return 1;
    }
    batchMode = true;
  }
  if (argc > 0) {
    singleStmt = argv[0];
    batchMode = true;
  }
  if (! batchMode)
    ndbout << "NDB Cluster NDB SQL -- A simple SQL Command-line Interface\n\n";

  Con con(dsn);
  if (do_connect(con) < 0)
    return 1;
  if (! batchMode)
    ndbout << "Terminate SQL statements with a semi-colon ';'\n";

  char* line = 0;
  char* line2 = 0;
  char* line3 = 0;
  unsigned lineno = 0;
  bool has_semi;
  bool exit_on_error = false;
  int exit_code = 0;
  while (1) {
    free(line);
    line = 0;
    lineno = 0;

more_lines:
    free(line2);
    free(line3);
    line2 = line3 = 0;
    lineno++;
    has_semi = false;
    char prompt[20];
    if (lineno == 1)
      strcpy(prompt, "SQL> ");
    else
      sprintf(prompt, "%4d ", lineno);
    if (singleStmt != 0) {
      line = strdup(singleStmt);
      int n = strlen(line);
      while (n > 0 && isspace(line[n - 1])) {
        line[--n] = 0;
      }
      if (n > 0 && line[n - 1] == ';')
        line[n - 1] = 0;
      has_semi = true;  // regardless
    } else {
      const char *line1 = readline_gets(prompt, batchMode, inputFile); 
      if (line1 != 0) {
        if (line == 0)
          line = strdup(line1);
        else {
          line = (char*)realloc(line, strlen(line) + 1 + strlen(line1) + 1);
          strcat(line, "\n");
          strcat(line, line1);
        }
        if (batchMode)
          ndbout << prompt << line1 << endl;
      } else {
        if (! batchMode)
          ndbout << endl;
        if (line != 0)
          ndbout << "Ignored unterminated SQL statement" << endl;
        break;
      }
    }

    line2 = (char*)malloc(strlen(line) + 1);
    {
      char* p = line2;
      char* q = line;
      bool str = false;
      while (*q != 0) {
        if (*q == '\'') {
          str = !str;
          *p++ = *q++;
        } else if (!str && *q == '-' && *(q + 1) == '-') {
          while (*q != 0 && *q != '\n')
            q++;
        } else
          *p++ = *q++;
      }
      *p = 0;
      int n = strlen(line2);
      while (n > 0 && isspace(line2[n - 1]))
        line2[--n] = 0;
      if (n > 0 && line2[n - 1] == ';') {
        line2[--n] = 0;
        has_semi = true;
      }
    }
    line3 = strdup(line2);
    char* tok[10];
    int ntok = 0;
    tok[ntok] = strtok(line3, " ");
    while (tok[ntok] != 0) {
      ntok++;
      if (ntok == 10)
        break;
      tok[ntok] = strtok(0, " ");
    }
    if (ntok == 0)
      continue;

    if (!strcasecmp(tok[0], "help") || !strcmp(tok[0], "?")) {
      if (ntok != 2)
	print_help();
      else if (!strcasecmp(tok[1], "create"))
	print_help_create();
      else if (!strcasecmp(tok[1], "insert"))
	print_help_insert();
      else if (strcasecmp(tok[1], "select"))
	print_help_select();
      else if (!strcasecmp(tok[1], "delete"))
	print_help_update();
      else if (!strcasecmp(tok[1], "update"))
	print_help_update();
      else if (!strcasecmp(tok[1], "virtual"))
	print_help_virtual();
      else
	print_help();
      continue;
    }

    if (!strcasecmp(tok[0], "list")) {
      if (ntok == 2 && !strcasecmp(tok[1], "tables")) {
	free(line2);
	line2 = strdup("SELECT TABLE_NAME FROM ODBC$TABLES");
        has_semi = true;
      } else {
        ndbout << "Invalid list option - try help" << endl;
        continue;
      }
    }

    if (ntok == 1 && !strcasecmp(tok[0], "quit"))
      break;
    if (ntok == 1 && !strcasecmp(tok[0], "exit"))
      break;
    if (ntok == 1 && !strcasecmp(tok[0], "bye"))
      break;

    if (!strcasecmp(tok[0], "set")) {
      if (ntok == 1) {
	char* p;
	p = getenv("NDB_ODBC_TRACE");
	ndbout << "Trace level is " << (p ? atoi(p) : 0) << endl;
	int ret = get_autocommit(con);
	if (ret != -1)
	  ndbout << "Autocommit is " << (ret == SQL_AUTOCOMMIT_ON ? "on" : "off") << endl;
      } else if (ntok == 3 && !strcasecmp(tok[1], "trace")) {
	static char env[40];
	int n = tok[2] ? atoi(tok[2]) : 0;
	sprintf(env, "NDB_ODBC_TRACE=%d", n);
	putenv(env);
	ndbout << "Trace level set to " << n << endl;
      } else if (ntok == 3 && !strcasecmp(tok[1], "autocommit")) {
	if (tok[2] && !strcasecmp(tok[2], "on")) {
	  int ret = set_autocommit(con, SQL_AUTOCOMMIT_ON);
	  if (ret != -1)
	    ndbout << "Autocommit set to ON" << endl;
	} else if (tok[2] && !strcasecmp(tok[2], "off")) {
	  int ret = set_autocommit(con, SQL_AUTOCOMMIT_OFF);
	  if (ret != -1)
	    ndbout << "Autocommit set to OFF - transaction may time out" << endl;
	} else {
	  ndbout << "Invalid autocommit option - try help" << endl;
	}
      } else {
	ndbout << "Invalid set command - try help" << endl;
      }
      continue;
    }

    if (ntok >= 2 &&
        !strcasecmp(tok[0], "whenever") && !strcasecmp(tok[1], "sqlerror")) {
      if (ntok == 3 && !strcasecmp(tok[2], "exit"))
        exit_on_error = true;
      else if (ntok == 3 && !strcasecmp(tok[2], "continue"))
        exit_on_error = false;
      else {
        ndbout << "Invalid whenever clause - try help" << endl;
      }
      continue;
    }

    if (!strcasecmp(tok[0], "commit")) {
      if (ntok == 1) {
        if (do_commit(con) != -1)
          ndbout << "Commit done" << endl;
        else {
          exit_code = 1;
          if (exit_on_error) {
            ndbout << "Exit on error" << endl;
            break;
          }
        }
      } else {
        ndbout << "Invalid commit command - try help" << endl;
      }
      continue;
    }

    if (!strcasecmp(tok[0], "rollback")) {
      if (ntok == 1) {
        if (do_rollback(con) != -1)
          ndbout << "Rollback done" << endl;
        else {
          exit_code = 1;
          if (exit_on_error) {
            ndbout << "Exit on error" << endl;
            break;
          }
        }
      } else {
        ndbout << "Invalid commit command - try help" << endl;
      }
      continue;
    }

    if (! has_semi)
      goto more_lines;
    if (do_stmt(con, line2) != 0) {
      exit_code = 1;
      if (exit_on_error) {
        ndbout << "Exit on error" << endl;
        break;
      }
    }
    if (singleStmt)
      break;
  }
  do_disconnect(con);
  return exit_code;
}
Exemplo n.º 2
0
int main(int argc, char *argv[]) {
    _bcc_status      bcc;
    void            *buf;
    bool             client = false;
    int              count_read;
    int              count_written;
    int              count_xferred;
#ifdef USE_SB_FC
    int              err;
#endif // USE_SB_FC
    int              ferr;
    short            filenumr;
    short            filenums[MAX_SRV];
#ifdef USE_SB_FC
    short            info_count;
#endif // USE_SB_FC
    int              inx;
    int              len;
#ifdef USE_SB_FC
    short            list_inx;
#endif // USE_SB_FC
    int              loop = 10;
    char            *p;
    char             recv_buffer[BUFSIZ];
    char             send_buffer[MAX_SRV][BUFSIZ];
#ifdef USE_SB_FC
    int              socka1;
    int              socka2;
    int              sockc1[MAX_SRV];
    int              sockc2[MAX_SRV];
    int              sockl;
#endif // USE_SB_FC
    int              srv;
    SB_Tag_Type      tag;
    short            tfilenum;
    int              timeout = -1;
    TAD              zargs[] = {
      { "-client",    TA_Bool, TA_NOMAX,    &client    },
      { "-loop",      TA_Int,  TA_NOMAX,    &loop      },
      { "-maxcp",     TA_Next, TA_NOMAX,    NULL       },
      { "-maxsp",     TA_Next, TA_NOMAX,    NULL       },
      { "-server",    TA_Ign,  TA_NOMAX,    NULL       },
      { "-v",         TA_Bool, TA_NOMAX,    &verbose   },
      { "",           TA_End,  TA_NOMAX,    NULL       }
    };

    ferr = file_init(&argc, &argv);
    TEST_CHK_FEOK(ferr);
    msfs_util_init_fs(&argc, &argv, file_debug_hook);
    arg_proc_args(zargs, false, argc, argv);
    util_test_start(client);
    ferr = file_mon_process_startup(!client); // system messages
    TEST_CHK_FEOK(ferr);

    if (client) {
#ifdef USE_SB_FC
        // check empty list
        ferr = BFILE_COMPLETE_GETINFO_((short *) info_list,
                                       MAX_INFO_LIST,
                                       &info_count);
        TEST_CHK_FEOK(ferr);
        assert(info_count == 0);
        // add bogus
        add_list[0].z_fnum_fd = 99;
        add_list[0].u_z_options.z_options.z_set_file = 0; // set
        add_list[0].u_z_options.z_options.z_filetype = 0; // guardian
        ferr = BFILE_COMPLETE_SET_((short *) add_list,
                                   1,
                                   &list_inx);
        assert(ferr == XZFIL_ERR_NOTFOUND);
        assert(list_inx == 0);

#endif // USE_SB_FC
        for (srv = 0; srv < MAX_SRV; srv++) {
            sprintf(send_buffer[srv], "$srv%d", srv);
            len = (int) strlen(send_buffer[srv]);
            ferr = BFILE_OPEN_((char *) send_buffer[srv], (short) len, &filenums[srv],
                               0, 0, 1,
                               0, 0, 0, 0, NULL);
            TEST_CHK_FEOK(ferr);
        }

#ifdef USE_SB_FC
        do_set_guardian(filenums[0], 0, 1); // add
        do_set_guardian(filenums[0], 1, 0); // remove (specific)
        do_set_guardian(filenums[0], 0, 1); // add
        do_set_guardian(-1, 1, 0);          // remove (all)
        do_set_guardian(-1, 0, 1);          // add (all)
#endif // USE_SB_FC

        for (srv = 0; srv < MAX_SRV; srv++) {
            for (inx = 0; inx < loop; inx++) {
                sprintf(send_buffer[srv], "inx=%d", inx);
                bcc = BWRITEREADX(filenums[srv],
                                  send_buffer[srv],
                                  (short) (strlen(send_buffer[srv]) + 1),
                                  BUFSIZ,
                                  &count_read,
                                  1);
                TEST_CHK_BCCEQ(bcc);
#ifdef USE_SB_FC
                ferr = BFILE_COMPLETE_((short *) &info,
                                        timeout,
                                        NULL,
                                        0,
                                        NULL);
                TEST_CHK_FEOK(ferr);
                assert(info.z_tag == 1);
#else
                tfilenum = -1;
                bcc = BAWAITIOX(&tfilenum,
                                &buf,
                                &count_xferred,
                                &tag,
                                timeout,
                                NULL);
                TEST_CHK_BCCEQ(bcc);
#endif
            }
        }
        for (srv = 0; srv < MAX_SRV; srv++) {
            p = strchr(send_buffer[srv], ':');
            *p = 0;
            p++;
            strcpy(host[srv], send_buffer[srv]);
            port[srv] = (unsigned short) atoi(p);
            if (verbose)
                printf("server[%d] returned host=%s, port=%d\n",
                       srv, host[srv], port[srv]);
        }

#ifdef USE_SB_FC
        if (verbose)
            printf("client connecting up\n");
        // connect up, and setup fds
        for (srv = 0; srv < MAX_SRV; srv++) {
            sockc1[srv] = do_connect(srv);
            sockc2[srv] = do_connect(srv);
        }
        do_set_guardian(-1, 1, 0);                 // remove (all)
        do_set_linux(sockc1[0], 0, 0, 0, 0, 1);    // add-no rr/wr/exc

        // nothing should be ready
        timeout = 0;
        ferr = BFILE_COMPLETE_((short *) &info,
                               timeout,
                               NULL,
                               0,
                               NULL);
        assert(ferr == XZFIL_ERR_TIMEDOUT);

        // server has sent something, so rr should be on
        sleep(1);
        do_set_linux(sockc1[0], 0, 1, 0, 0, 1); // rr
        timeout = -1;
        ferr = BFILE_COMPLETE_((short *) &info,
                               timeout,
                               NULL,
                               0,
                               NULL);
        TEST_CHK_FEOK(ferr);
        assert(info.z_filetype); // linux
        assert(info.z_error == XZFIL_ERR_OK);
        assert(info.z_fnum_fd == sockc1[0]);
        assert(info.u_z_return_value.z_return_value.z_read_ready);
        assert(!info.u_z_return_value.z_return_value.z_write_ready);
        assert(!info.u_z_return_value.z_return_value.z_exception);

        // wr should be on
        do_set_linux(sockc1[0], 0, 0, 1, 0, 1); // wr
        timeout = -1;
        ferr = BFILE_COMPLETE_((short *) &info,
                               timeout,
                               NULL,
                               0,
                               NULL);
        TEST_CHK_FEOK(ferr);
        assert(info.z_filetype); // linux
        assert(info.z_error == XZFIL_ERR_OK);
        assert(info.z_fnum_fd == sockc1[0]);
        assert(!info.u_z_return_value.z_return_value.z_read_ready);
        assert(info.u_z_return_value.z_return_value.z_write_ready);
        assert(!info.u_z_return_value.z_return_value.z_exception);

        do_set_linux(sockc1[0], 0, 0, 0, 0, 1);    // clear ready
        do_set_linux(sockc2[0], 0, 0, 0, 0, 2);    // add-no rr/wr/exc

        // nothing should be ready
        timeout = 0;
        ferr = BFILE_COMPLETE_((short *) &info,
                               timeout,
                               NULL,
                               0,
                               NULL);
        assert(ferr == XZFIL_ERR_TIMEDOUT);

        // rr should NOT be ready
        do_set_linux(sockc2[0], 0, 1, 0, 0, 2); // rr
        timeout = 100;
        ferr = BFILE_COMPLETE_((short *) &info,
                               timeout,
                               NULL,
                               0,
                               NULL);
        assert(ferr == XZFIL_ERR_TIMEDOUT);

        // test fairness (check trace)
        do_set_linux(-1, 1, 0, 0, 0, 0);  // clear linux
        for (srv = 0; srv < MAX_SRV; srv++)
            do_set_guardian(filenums[srv], 0, srv + 1); // add
        for (srv = 0; srv < MAX_SRV; srv++) {
            bcc = BWRITEREADX(filenums[srv],
                              NULL,
                              0,
                              BUFSIZ,
                              &count_read,
                              1);
            TEST_CHK_BCCEQ(bcc);
        }
        usleep(10000);
        for (srv = 0; srv < MAX_SRV; srv++) {
            timeout = -1;
            ferr = BFILE_COMPLETE_((short *) &info,
                                   timeout,
                                   NULL,
                                   0,
                                   NULL);
            TEST_CHK_FEOK(ferr);
            assert(!info.z_filetype); // guardian
            assert(info.z_error == XZFIL_ERR_OK);
            assert(info.z_fnum_fd == filenums[srv]);
        }
#endif // USE_SB_FC

        if (verbose)
            printf("client closing\n");
        for (srv = 0; srv < MAX_SRV; srv++) {
            ferr = BFILE_CLOSE_(filenums[srv], 0);
            TEST_CHK_FEOK(ferr);
        }
        printf("if there were no asserts, all is well\n");
    } else {
#ifdef USE_SB_FC
        sockl = do_listen();
        assert(sockl != -1);
#endif // USE_SB_FC

        ferr = BFILE_OPEN_((char *) "$RECEIVE", 8, &filenumr,
                           0, 0, 1,
                           1, 1, // no sys msg
                           0, 0, NULL);
        TEST_CHK_FEOK(ferr);
        for (inx = 0; inx < loop; inx++) {
            bcc = BREADUPDATEX(filenumr,
                               recv_buffer,
                               BUFSIZ,
                               &count_read,
                               1);
            TEST_CHK_BCCEQ(bcc);
            tfilenum = filenumr;
            bcc = BAWAITIOX(&tfilenum,
                            &buf,
                            &count_xferred,
                            &tag,
                            timeout,
                            NULL);
            TEST_CHK_BCCEQ(bcc);
            assert(tag == 1);
            sprintf(recv_buffer, "%s:%d\n", host[0], port[0]);
            count_read = (short) (strlen(recv_buffer) + 1);
            bcc = BREPLYX(recv_buffer,
                          count_read,
                          &count_written,
                          0,
                          XZFIL_ERR_OK);
            TEST_CHK_BCCEQ(bcc);
        }

#ifdef USE_SB_FC
        if (verbose)
            printf("server accepting\n");
        socka1 = do_accept(sockl);
        socka2 = do_accept(sockl);
        err = write(socka1, recv_buffer, 1);
        assert(err == 1);

        for (inx = 0; inx < 1; inx++) {
            bcc = BREADUPDATEX(filenumr,
                               recv_buffer,
                               BUFSIZ,
                               &count_read,
                               1);
            TEST_CHK_BCCEQ(bcc);
            tfilenum = filenumr;
            bcc = BAWAITIOX(&tfilenum,
                            &buf,
                            &count_xferred,
                            &tag,
                            timeout,
                            NULL);
            TEST_CHK_BCCEQ(bcc);
            bcc = BREPLYX(recv_buffer,
                          0,
                          &count_written,
                          0,
                          XZFIL_ERR_OK);
            TEST_CHK_BCCEQ(bcc);
        }
#endif // USE_SB_FC

        if (verbose)
            printf("server closing\n");
        ferr = BFILE_CLOSE_(filenumr, 0);
        TEST_CHK_FEOK(ferr);
    }
    ferr = file_mon_process_shutdown();
    TEST_CHK_FEOK(ferr);
    util_test_finish(client);
    return 0;
}