Esempio n. 1
0
void
basicFunctionHelper(sqlite3_context *aCtx,
                    int aArgc,
                    sqlite3_value **aArgv)
{
  void *userData = ::sqlite3_user_data(aCtx);

  mozIStorageFunction *func = static_cast<mozIStorageFunction *>(userData);

  nsRefPtr<ArgValueArray> arguments(new ArgValueArray(aArgc, aArgv));
  if (!arguments)
      return;

  nsCOMPtr<nsIVariant> result;
  if (NS_FAILED(func->OnFunctionCall(arguments, getter_AddRefs(result)))) {
    NS_WARNING("User function returned error code!");
    ::sqlite3_result_error(aCtx,
                           "User function returned error code",
                           -1);
    return;
  }
  int retcode = variantToSQLiteT(aCtx, result);
  if (retcode == SQLITE_IGNORE) {
    ::sqlite3_result_int(aCtx, SQLITE_IGNORE);
  } else if (retcode != SQLITE_OK) {
    NS_WARNING("User function returned invalid data type!");
    ::sqlite3_result_error(aCtx,
                           "User function returned invalid data type",
                           -1);
  }
}
already_AddRefed<mozIStorageError>
AsyncBindingParams::bind(sqlite3_stmt * aStatement)
{
  // We should bind by index using the super-class if there is nothing in our
  // hashtable.
  if (!mNamedParameters.Count())
    return BindingParams::bind(aStatement);

  nsCOMPtr<mozIStorageError> err;

  for (auto iter = mNamedParameters.Iter(); !iter.Done(); iter.Next()) {
    const nsACString &key = iter.Key();

    // We do not accept any forms of names other than ":name", but we need to
    // add the colon for SQLite.
    nsAutoCString name(":");
    name.Append(key);
    int oneIdx = ::sqlite3_bind_parameter_index(aStatement, name.get());

    if (oneIdx == 0) {
      nsAutoCString errMsg(key);
      errMsg.AppendLiteral(" is not a valid named parameter.");
      err = new Error(SQLITE_RANGE, errMsg.get());
      break;
    }

    // XPCVariant's AddRef and Release are not thread-safe and so we must not
    // do anything that would invoke them here on the async thread.  As such we
    // can't cram aValue into mParameters using ReplaceObjectAt so that
    // we can freeload off of the BindingParams::Bind implementation.
    int rc = variantToSQLiteT(BindingColumnData(aStatement, oneIdx - 1),
                              iter.UserData());
    if (rc != SQLITE_OK) {
      // We had an error while trying to bind.  Now we need to create an error
      // object with the right message.  Note that we special case
      // SQLITE_MISMATCH, but otherwise get the message from SQLite.
      const char *msg = "Could not covert nsIVariant to SQLite type.";
      if (rc != SQLITE_MISMATCH) {
        msg = ::sqlite3_errmsg(::sqlite3_db_handle(aStatement));
      }
      err = new Error(rc, msg);
      break;
    }
  }

  return err.forget();
}
PLDHashOperator
AsyncBindingParams::iterateOverNamedParameters(const nsACString &aName,
                                               nsIVariant *aValue,
                                               void *voidClosureThunk)
{
  NamedParameterIterationClosureThunk *closureThunk =
    static_cast<NamedParameterIterationClosureThunk *>(voidClosureThunk);

  // We do not accept any forms of names other than ":name", but we need to add
  // the colon for SQLite.
  nsAutoCString name(":");
  name.Append(aName);
  int oneIdx = ::sqlite3_bind_parameter_index(closureThunk->statement,
                                              name.get());

  if (oneIdx == 0) {
    nsAutoCString errMsg(aName);
    errMsg.Append(NS_LITERAL_CSTRING(" is not a valid named parameter."));
    closureThunk->err = new Error(SQLITE_RANGE, errMsg.get());
    return PL_DHASH_STOP;
  }

  // XPCVariant's AddRef and Release are not thread-safe and so we must not do
  // anything that would invoke them here on the async thread.  As such we can't
  // cram aValue into self->mParameters using ReplaceObjectAt so that we can
  // freeload off of the BindingParams::Bind implementation.
  int rc = variantToSQLiteT(BindingColumnData(closureThunk->statement,
                                              oneIdx - 1),
                            aValue);
  if (rc != SQLITE_OK) {
    // We had an error while trying to bind.  Now we need to create an error
    // object with the right message.  Note that we special case
    // SQLITE_MISMATCH, but otherwise get the message from SQLite.
    const char *msg = "Could not covert nsIVariant to SQLite type.";
    if (rc != SQLITE_MISMATCH)
      msg = ::sqlite3_errmsg(::sqlite3_db_handle(closureThunk->statement));

    closureThunk->err = new Error(rc, msg);
    return PL_DHASH_STOP;
  }
  return PL_DHASH_NEXT;
}
already_AddRefed<mozIStorageError>
BindingParams::bind(sqlite3_stmt *aStatement)
{
  // Iterate through all of our stored data, and bind it.
  for (size_t i = 0; i < mParameters.Length(); i++) {
    int rc = variantToSQLiteT(BindingColumnData(aStatement, i), mParameters[i]);
    if (rc != SQLITE_OK) {
      // We had an error while trying to bind.  Now we need to create an error
      // object with the right message.  Note that we special case
      // SQLITE_MISMATCH, but otherwise get the message from SQLite.
      const char *msg = "Could not covert nsIVariant to SQLite type.";
      if (rc != SQLITE_MISMATCH)
        msg = ::sqlite3_errmsg(::sqlite3_db_handle(aStatement));

      nsCOMPtr<mozIStorageError> err(new Error(rc, msg));
      return err.forget();
    }
  }

  return nullptr;
}
Esempio n. 5
0
void
aggregateFunctionFinalHelper(sqlite3_context *aCtx)
{
  void *userData = ::sqlite3_user_data(aCtx);
  mozIStorageAggregateFunction *func =
    static_cast<mozIStorageAggregateFunction *>(userData);

  nsRefPtr<nsIVariant> result;
  if (NS_FAILED(func->OnFinal(getter_AddRefs(result)))) {
    NS_WARNING("User aggregate final function returned error code!");
    ::sqlite3_result_error(aCtx,
                           "User aggregate final function returned error code",
                           -1);
    return;
  }

  if (variantToSQLiteT(aCtx, result) != SQLITE_OK) {
    NS_WARNING("User aggregate final function returned invalid data type!");
    ::sqlite3_result_error(aCtx,
                           "User aggregate final function returned invalid data type",
                           -1);
  }
}