예제 #1
0
 @Override
 public void copySpecialInstanceVariables(IRubyObject clone) {
   RubyRange range = (RubyRange) clone;
   range.begin = begin;
   range.end = end;
   range.isExclusive = isExclusive;
 }
예제 #2
0
파일: Command.java 프로젝트: gryn/do
  /**
   * 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);
      }
    }
  }
예제 #3
0
 public static RubyRange newRange(
     Ruby runtime,
     ThreadContext context,
     IRubyObject begin,
     IRubyObject end,
     boolean isExclusive) {
   RubyRange range = new RubyRange(runtime, runtime.getRange());
   range.init(context, begin, end, isExclusive);
   return range;
 }
예제 #4
0
        public void marshalTo(Ruby runtime, Object obj, RubyClass type, MarshalStream marshalStream)
            throws IOException {
          RubyRange range = (RubyRange) obj;

          marshalStream.registerLinkTarget(range);
          List<Variable<IRubyObject>> attrs = range.getVariableList();

          attrs.add(new VariableEntry<IRubyObject>("begin", range.begin));
          attrs.add(new VariableEntry<IRubyObject>("end", range.end));
          attrs.add(
              new VariableEntry<IRubyObject>(
                  "excl", range.isExclusive ? runtime.getTrue() : runtime.getFalse()));

          marshalStream.dumpVariables(attrs);
        }
예제 #5
0
 private static RangeLike rangeValues(ThreadContext context, IRubyObject range) {
   RangeLike like = new RangeLike();
   if (range instanceof RubyRange) {
     RubyRange vrange = (RubyRange) range;
     like.begin = vrange.first(context);
     like.end = vrange.last(context);
     like.excl = vrange.exclude_end_p().isTrue();
   } else {
     if (!range.respondsTo("begin")
         || !range.respondsTo("end")
         || !range.respondsTo("exclude_end?")) {
       return null;
     }
     like.begin = Helpers.invoke(context, range, "begin");
     like.end = Helpers.invoke(context, range, "end");
     like.excl = Helpers.invoke(context, range, "exlucde_end?").isTrue();
   }
   like.range = Helpers.invoke(context, like.end, "-", like.begin);
   return like;
 }
예제 #6
0
        public Object unmarshalFrom(Ruby runtime, RubyClass type, UnmarshalStream unmarshalStream)
            throws IOException {
          RubyRange range = (RubyRange) type.allocate();

          unmarshalStream.registerLinkTarget(range);

          unmarshalStream.defaultVariablesUnmarshal(range);

          range.begin = (IRubyObject) range.removeInternalVariable("begin");
          range.end = (IRubyObject) range.removeInternalVariable("end");
          range.isExclusive = ((IRubyObject) range.removeInternalVariable("excl")).isTrue();

          return range;
        }
예제 #7
0
 public static RubyRange newInclusiveRange(
     Ruby runtime, ThreadContext context, IRubyObject begin, IRubyObject end) {
   RubyRange range = new RubyRange(runtime, runtime.getRange());
   range.init(context, begin, end, false);
   return range;
 }
예제 #8
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);
      }
    }
  }