コード例 #1
0
ファイル: ext_mysql.cpp プロジェクト: Bluarggag/hhvm
int64_t f_mysql_async_status(CVarRef link_identifier) {
  MySQL *mySQL = MySQL::Get(link_identifier);
  if (!mySQL || !mySQL->get()) {
    raise_warning("supplied argument is not a valid MySQL-Link resource");
    return -1;
  }

  return mySQL->get()->async_op_status;
}
コード例 #2
0
ファイル: ext_mysql.cpp プロジェクト: CodeKong/hhvm
static int64_t HHVM_FUNCTION(mysql_async_status,
                             const Variant& link_identifier) {
  MySQL *mySQL = MySQL::Get(link_identifier);
  if (!mySQL || !mySQL->get()) {
    raise_warning("supplied argument is not a valid MySQL-Link resource");
    return -1;
  }

  return mySQL->get()->async_op_status;
}
コード例 #3
0
ファイル: ext_mysql.cpp プロジェクト: Bluarggag/hhvm
Variant f_mysql_async_query_result(CVarRef link_identifier) {
  MySQL* mySQL = MySQL::Get(link_identifier);
  if (!mySQL) {
    raise_warning("supplied argument is not a valid MySQL-Link resource");
    return Variant(Variant::NullInit());
  }
  MYSQL* conn = mySQL->get();
  if (!conn || (conn->async_op_status != ASYNC_OP_QUERY &&
                conn->async_op_status != ASYNC_OP_UNSET)) {
    raise_warning("runtime/ext_mysql: attempt to check query result when query "
                  "not executing");
    return Variant(Variant::NullInit());
  }

  int error = 0;
  auto status = mysql_real_query_nonblocking(
    conn, mySQL->m_async_query.data(), mySQL->m_async_query.size(), &error);

  if (status != NET_ASYNC_COMPLETE) {
    return Variant(Variant::NullInit());
  }

  if (error) {
    return Variant(Variant::NullInit());
  }

  mySQL->m_async_query.reset();

  MYSQL_RES* mysql_result = mysql_use_result(conn);
  MySQLResult *r = NEWOBJ(MySQLResult)(mysql_result);
  r->setAsyncConnection(mySQL);
  Resource ret(r);
  return ret;
}
コード例 #4
0
ファイル: ext_mysql.cpp プロジェクト: Bluarggag/hhvm
Variant f_mysql_warning_count(CVarRef link_identifier /* = null */) {
  MySQL *mySQL = MySQL::Get(link_identifier);
  if (!mySQL) {
    raise_warning("supplied argument is not a valid MySQL-Link resource");
    return false;
  }
  MYSQL *conn = mySQL->get();
  if (conn) {
    return (int64_t)mysql_warning_count(conn);
  }
  return false;
}
コード例 #5
0
ファイル: ext_mysql.cpp プロジェクト: Bluarggag/hhvm
Variant f_mysql_error(CVarRef link_identifier /* = null */) {
  MySQL *mySQL = MySQL::Get(link_identifier);
  if (!mySQL) {
    raise_warning("supplied argument is not a valid MySQL-Link resource");
    return false;
  }
  MYSQL *conn = mySQL->get();
  if (conn) {
    return String(mysql_error(conn), CopyString);
  }
  if (mySQL->m_last_error_set) {
    return String(mySQL->m_last_error);
  }
  return false;
}
コード例 #6
0
ファイル: ext_mysql.cpp プロジェクト: isgiker/hhvm
Variant f_mysql_errno(const Variant& link_identifier /* = null */) {
  MySQL *mySQL = MySQL::Get(link_identifier);
  if (!mySQL) {
    raise_warning("supplied argument is not a valid MySQL-Link resource");
    return false;
  }
  MYSQL *conn = mySQL->get();
  if (conn) {
    return (int64_t)mysql_errno(conn);
  }
  if (mySQL->m_last_error_set) {
    return (int64_t)mySQL->m_last_errno;
  }
  return false;
}
コード例 #7
0
ファイル: mysql_common.cpp プロジェクト: 2bj/hhvm
MYSQL *MySQL::GetConn(const Variant& link_identifier, MySQL **rconn /* = NULL */) {
  MySQL *mySQL = Get(link_identifier);
  MYSQL *ret = nullptr;
  if (mySQL) {
    ret = mySQL->get();
  }
  if (ret == nullptr) {
    raise_warning("supplied argument is not a valid MySQL-Link resource");
  }
  // Don't return a connection where mysql_real_connect() failed to most
  // f_mysql_* APIs (the ones that deal with errno where we do want to do this
  // anyway use MySQL::Get instead) as mysqlclient doesn't support passing
  // connections in that state and it can crash.
  if (mySQL && mySQL->m_last_error_set) {
    ret = nullptr;
  } else if (rconn) {
    *rconn = mySQL;
  }
  return ret;
}
コード例 #8
0
ファイル: ext_mysql.cpp プロジェクト: Bluarggag/hhvm
bool f_mysql_async_connect_completed(CVarRef link_identifier) {
  MySQL* mySQL = MySQL::Get(link_identifier);
  if (!mySQL) {
    raise_warning("supplied argument is not a valid MySQL-Link resource");
    return true;
  }

  MYSQL* conn = mySQL->get();
  if (conn->async_op_status != ASYNC_OP_CONNECT) {
    // Don't warn if we're in UNSET state (ie between queries, etc)
    if (conn->async_op_status != ASYNC_OP_UNSET) {
      raise_warning("runtime/ext_mysql: no pending async connect in progress");
    }
    return true;
  }

  int error = 0;
  auto status = mysql_real_connect_nonblocking_run(conn, &error);
  return status == NET_ASYNC_COMPLETE;
}
コード例 #9
0
ファイル: ext_mysql.cpp プロジェクト: Bluarggag/hhvm
// This function takes an array of arrays, each of which is of the
// form array($dbh, ...).  The only thing that matters in the inner
// arrays is the first element being a MySQL instance.  It then
// procedes to block for up to 'timeout' seconds, waiting for the
// first actionable descriptor(s), which it then returns in the form
// of the original arrays passed in.  The intention is the caller
// would include other information they care about in the tail of the
// array so they can decide how to act on the
// potentially-now-queryable descriptors.
//
// This function is a poor shadow of how the async library can be
// used; for more complex cases, we'd use libevent and share our event
// loop with other IO operations such as memcache ops, thrift calls,
// etc.  That said, this function is reasonably efficient for most use
// cases.
Variant f_mysql_async_wait_actionable(CVarRef items, double timeout) {
  size_t count = items.toArray().size();
  if (count == 0 || timeout < 0) {
    return Array::Create();
  }

  struct pollfd* fds = (struct pollfd*)calloc(count, sizeof(struct pollfd));
  SCOPE_EXIT { free(fds); };

  // Walk our input, determine what kind of poll() operation is
  // necessary for the descriptor in question, and put an entry into
  // fds.
  int nfds = 0;
  for (ArrayIter iter(items.toArray()); iter; ++iter) {
    Array entry = iter.second().toArray();
    if (entry.size() < 1) {
      raise_warning("element %d did not have at least one entry",
                   nfds);
      return Array::Create();
    }

    MySQL* mySQL = entry.rvalAt(0).toResource().getTyped<MySQL>();
    MYSQL* conn = mySQL->get();
    if (conn->async_op_status == ASYNC_OP_UNSET) {
      raise_warning("runtime/ext_mysql: no pending async operation in "
                    "progress");
      return Array::Create();
    }

    pollfd* fd = &fds[nfds++];
    fd->fd = mysql_get_file_descriptor(conn);
    if (conn->net.async_blocking_state == NET_NONBLOCKING_READ) {
      fd->events = POLLIN;
    } else {
      fd->events = POLLOUT;
    }
    fd->revents = 0;
  }

  // The poll itself; either the timeout is hit or one or more of the
  // input fd's is ready.
  int timeout_millis = static_cast<long>(timeout * 1000);
  int res = poll(fds, nfds, timeout_millis);
  if (res == -1) {
    raise_warning("unable to poll [%d]: %s", errno,
                  folly::errnoStr(errno).c_str());
    return Array::Create();
  }

  // Now just find the ones that are ready, and copy the corresponding
  // arrays from our input array into our return value.
  Array ret = Array::Create();
  nfds = 0;
  for (ArrayIter iter(items.toArray()); iter; ++iter) {
    Array entry = iter.second().toArray();
    if (entry.size() < 1) {
      raise_warning("element %d did not have at least one entry",
                   nfds);
      return Array::Create();
    }
    MySQL* mySQL = entry.rvalAt(0).toResource().getTyped<MySQL>();
    MYSQL* conn = mySQL->get();

    pollfd* fd = &fds[nfds++];
    if (fd->fd != mysql_get_file_descriptor(conn)) {
      raise_warning("poll returned events out of order wtf");
      continue;
    }
    if (fd->revents != 0) {
      ret.append(iter.second());
    }
  }

  return ret;
}