Exemple #1
0
  /** Compatibility with Tempfile#make_tmpname(basename, n) in MRI */
  @JRubyMethod(visibility = PRIVATE)
  public IRubyObject make_tmpname(
      ThreadContext context, IRubyObject basename, IRubyObject n, Block block) {
    Ruby runtime = context.getRuntime();
    IRubyObject[] newargs = new IRubyObject[5];

    IRubyObject base, suffix;
    if (basename instanceof RubyArray) {
      RubyArray array = (RubyArray) basename;
      int length = array.getLength();

      base = length > 0 ? array.eltInternal(0) : runtime.getNil();
      suffix = length > 0 ? array.eltInternal(1) : runtime.getNil();
    } else {
      base = basename;
      suffix = runtime.newString("");
    }

    newargs[0] = runtime.newString("%s.%d.%d%s");
    newargs[1] = base;
    newargs[2] = runtime.getGlobalVariables().get("$$"); // PID
    newargs[3] = n;
    newargs[4] = suffix;
    return callMethod(context, "sprintf", newargs);
  }
Exemple #2
0
  /**
   * Assist with setting the parameter values on a PreparedStatement
   *
   * @param ps the PreparedStatement for which parameters should be set
   * @param recv
   * @param args an array of parameter values
   */
  private static void prepareStatementFromArgs(
      PreparedStatement ps, IRubyObject recv, IRubyObject[] args) {
    int index = 1;
    try {
      for (IRubyObject arg : args) {

        // Handle multiple valued arguments, i.e. arrays + ranges

        if (arg instanceof RubyArray) {
          // Handle a RubyArray passed into a query
          //
          // NOTE: This should not call ps.setArray(i,v) as this is
          // designed to work with the SQL Array type, and in most cases
          // is not what we want.
          // Instead, this functionality is for breaking down a Ruby
          // array of ["a","b","c"] into SQL "('a','b','c')":
          //
          // So, in this case, we actually want to augment the number of
          // ? params in the PreparedStatement query appropriately.

          RubyArray array_value = arg.convertToArray();

          for (int j = 0; j < array_value.getLength(); j++) {
            setPreparedStatementParam(ps, recv, array_value.eltInternal(j), index++);
          }

        } else if (arg instanceof RubyRange) {
          // Handle a RubyRange passed into a query
          //
          // NOTE: see above - need to augment the number of ? params
          // in the PreparedStatement: (? AND ?)

          RubyRange range_value = (RubyRange) arg;

          setPreparedStatementParam(ps, recv, range_value.first(), index++);
          setPreparedStatementParam(ps, recv, range_value.last(), index++);

        } else {
          // Otherwise, handle each argument
          setPreparedStatementParam(ps, recv, arg, index++);
        }
      }
    } catch (SQLException sqle) {
      // TODO: log sqle.printStackTrace();
      // TODO: possibly move this exception string parsing somewhere else
      Pattern pattern =
          Pattern.compile(
              "Parameter index out of bounds. (\\d+) is not between valid values of (\\d+) and (\\d+)");
      Matcher matcher = pattern.matcher(sqle.getMessage());
      if (matcher.matches()) {
        throw recv.getRuntime()
            .newArgumentError(
                String.format(
                    "Binding mismatch: %1$d for %2$d",
                    Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2))));
      } else {
        throw DataObjectsUtils.newDriverError(recv.getRuntime(), errorName, sqle);
      }
    }
  }
  @Override
  public long[] toNative(IRubyObject value, ToNativeContext context) {
    RubyArray rbArray = value.convertToArray();
    long[] arr = new long[rbArray.getLength()];

    if (ArrayFlags.isIn(arrayFlags)) {
      for (int i = 0; i < arr.length; i++) {
        arr[i] = Util.longValue(rbArray.entry(i));
      }
    }

    return arr;
  }
  @Override
  public void assignArray(
      Ruby runtime, ThreadContext context, IRubyObject self, IRubyObject arg, Block block) {
    RubyArray values = (RubyArray) arg;
    int valueLength = values.getLength();

    switch (valueLength) {
      case 0:
        assign(runtime, context, self, block);
        break;
      case 1:
        assign(runtime, context, self, values.eltInternal(0), block);
        break;
      case 2:
        assign(runtime, context, self, values.eltInternal(0), values.eltInternal(1), block);
        break;
      case 3:
        assign(
            runtime,
            context,
            self,
            values.eltInternal(0),
            values.eltInternal(1),
            values.eltInternal(2),
            block);
        break;
    }

    // Populate up to shorter of calling arguments or local parameters in the block
    for (int i = 0; i < preLength && i < valueLength; i++) {
      pre.get(i).assign(runtime, context, self, values.eltInternal(i), block, false);
    }

    // nil pad since we provided less values than block parms
    if (valueLength < preLength) {
      assignNilTo(runtime, context, self, block, valueLength);
    } else if (valueLength == preLength) { // no extra args for rest
      rest.assign(
          runtime, context, self, runtime.newArrayNoCopyLight(IRubyObject.NULL_ARRAY), block, true);
    } else { // extra args for rest
      rest.assign(
          runtime,
          context,
          self,
          values.subseqLight(preLength, valueLength - preLength),
          block,
          true);
    }
  }
Exemple #5
0
 @Override
 public void accept(ThreadContext context, SaveContextVisitor visitor) {
   visitor.enter((Element) node);
   XmlNodeSet xmlNodeSet = (XmlNodeSet) children(context);
   if (xmlNodeSet.length() > 0) {
     RubyArray array = (RubyArray) xmlNodeSet.to_a(context);
     for (int i = 0; i < array.getLength(); i++) {
       Object item = array.get(i);
       if (item instanceof XmlNode) {
         XmlNode cur = (XmlNode) item;
         cur.accept(context, visitor);
       } else if (item instanceof XmlNamespace) {
         XmlNamespace cur = (XmlNamespace) item;
         cur.accept(context, visitor);
       }
     }
   }
   visitor.leave((Element) node);
 }
Exemple #6
0
  @Override
  public Object interpret(
      ThreadContext context,
      IRubyObject self,
      IRubyObject[] args,
      Block block,
      Object exception,
      Object[] temp) {
    IRubyObject receiver = (IRubyObject) arg1.retrieve(context, self, temp);
    IRubyObject value = (IRubyObject) arg2.retrieve(context, self, temp);

    if (value == UndefinedValue.UNDEFINED) {
      result.store(context, self, temp, receiver);
    } else if (receiver instanceof RubyArray) {
      RubyArray testVals = (RubyArray) receiver;
      for (int i = 0, n = testVals.getLength(); i < n; i++) {
        IRubyObject excType = (IRubyObject) testVals.eltInternal(i);
        if (!(excType instanceof RubyModule)) {
          throw context
              .getRuntime()
              .newTypeError("class or module required for rescue clause. Found: " + excType);
        }
        IRubyObject eqqVal = excType.callMethod(context, "===", value);
        if (eqqVal.isTrue()) {
          result.store(context, self, temp, eqqVal);
          return null;
        }
      }
      result.store(context, self, temp, context.getRuntime().newBoolean(false));
    } else {
      if (!(receiver instanceof RubyModule)) {
        throw context
            .getRuntime()
            .newTypeError("class or module required for rescue clause. Found: " + receiver);
      }
      result.store(context, self, temp, receiver.callMethod(context, "===", value));
    }

    return null;
  }
Exemple #7
0
  /**
   * Assist with setting the parameter values on a PreparedStatement
   *
   * @param sqlText
   * @param ps the PreparedStatement for which parameters should be set
   * @param args an array of parameter values
   * @return true if there is return parameter, false if there is not
   */
  private boolean prepareStatementFromArgs(
      String sqlText, PreparedStatement ps, IRubyObject[] args) {
    int index = 1;
    boolean hasReturnParam = false;
    try {
      int psCount = ps.getParameterMetaData().getParameterCount();
      // fail fast
      if (args.length > psCount) {
        throw getRuntime().newArgumentError("Binding mismatch: " + args.length + " for " + psCount);
      }
      for (IRubyObject arg : args) {

        // Handle multiple valued arguments, i.e. arrays + ranges

        if (arg instanceof RubyArray) {
          // Handle a RubyArray passed into a query
          //
          // NOTE: This should not call ps.setArray(i,v) as this is
          // designed to work with the SQL Array type, and in most cases
          // is not what we want.
          // Instead, this functionality is for breaking down a Ruby
          // array of ["a","b","c"] into SQL "('a','b','c')":
          //
          // So, in this case, we actually want to augment the number of
          // ? params in the PreparedStatement query appropriately.

          RubyArray arrayValues = arg.convertToArray();

          for (int j = 0; j < arrayValues.getLength(); j++) {
            driver.setPreparedStatementParam(ps, arrayValues.eltInternal(j), index++);
          }
        } else if (arg instanceof RubyRange) {
          // Handle a RubyRange passed into a query
          //
          // NOTE: see above - need to augment the number of ? params
          // in the PreparedStatement: (? AND ?)

          RubyRange range_value = (RubyRange) arg;

          driver.setPreparedStatementParam(ps, range_value.first(), index++);
          driver.setPreparedStatementParam(ps, range_value.last(), index++);

        } else {
          // Otherwise, handle each argument
          driver.setPreparedStatementParam(ps, arg, index++);
        }
      }

      // callback for binding RETURN ... INTO ... output parameter
      if (driver.registerPreparedStatementReturnParam(sqlText, ps, index)) {
        index++;
        hasReturnParam = true;
      }

      if ((index - 1) < psCount) {
        throw getRuntime().newArgumentError("Binding mismatch: " + (index - 1) + " for " + psCount);
      }
      return hasReturnParam;
    } catch (SQLException sqle) {
      // TODO: possibly move this exception string parsing somewhere else
      Pattern pattern =
          Pattern.compile(
              "Parameter index out of bounds. (\\d+) is not between valid values of (\\d+) and (\\d+)");
      // POSTGRES: The column index is out of range: 2, number of columns: 1.
      // POSTGRES SQL STATE: 22023 (22023 "INVALID PARAMETER VALUE" invalid_parameter_value)
      // SQLITE3:  Does not throw a SQLException!
      // H2: Invalid value 2 for parameter parameterIndex [90008-63]
      // HSQLDB:      Invalid argument in JDBC call: parameter index out of range: 2
      // DERBY:       The parameter position '2' is out of range.  The number of parameters for this
      // prepared  statement is '1'
      // DERbY SQL CODE:  XCL13
      Matcher matcher = pattern.matcher(sqle.getMessage());
      if (matcher.matches()) {
        throw getRuntime()
            .newArgumentError(
                String.format(
                    "Binding mismatch: %1$d for %2$d",
                    Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2))));
      } else {
        throw Errors.newSqlError(getRuntime(), driver, sqle);
      }
    }
  }