예제 #1
0
  private void insertBatches() throws DaoException, SQLException, InterruptedException {
    boolean finished = false;

    Connection cnx = ds.getConnection();
    if (isPostGisLoader) {
      try {

        ((org.postgresql.PGConnection) cnx)
            .addDataType("geometry", Class.forName("org.postgis.PGgeometry"));
        //                ((org.postgresql.PGConnection) cnx).addDataType("geometry",
        // Class.forName("org.postgis.Multipolygon"));

      } catch (ClassNotFoundException e) {
        throw new DaoException(
            "Could not find PostGIS geometry type. Is the PostGIS library in the class path?: "
                + e.getMessage());
      }
    }

    PreparedStatement statement = null;
    try {
      String[] names = new String[fields.length];
      String[] questions = new String[fields.length];
      for (int i = 0; i < fields.length; i++) {
        names[i] = fields[i];
        questions[i] = "?";
      }
      String sql =
          "INSERT INTO "
              + table
              + "("
              + StringUtils.join(names, ",")
              + ") "
              + "VALUES ("
              + StringUtils.join(questions, ",")
              + ");";
      statement = cnx.prepareStatement(sql);

      while (!finished && inserterState != InserterState.FAILED) {
        // accumulate batch
        int batchSize = 0;
        while (!finished && batchSize < BATCH_SIZE && inserterState != InserterState.FAILED) {
          Object row[] = rowBuffer.poll(100, TimeUnit.MILLISECONDS);
          if (row == null) {
            // do nothing
          } else if (row[0] == POSION_PILL) {
            rowBuffer.put(new Object[] {POSION_PILL});
            finished = true;
          } else {
            batchSize++;
            for (int i = 0; i < row.length; i++) {
              if (row[i] != null && row[i].getClass().equals(java.lang.Character.class))
                statement.setObject(i + 1, row[i].toString());
              else statement.setObject(i + 1, row[i]);
            }
            statement.addBatch();
          }
        }
        try {
          statement.executeBatch();
          cnx.commit();
        } catch (SQLException e) {
          cnx.rollback();
          while (e != null) {
            LOG.error("insert batch failed, attempting to continue:", e);
            e = e.getNextException();
          }
        }
        statement.clearBatch();
      }
    } finally {
      if (statement != null) {
        JDBCUtils.safeClose(statement);
      }
      AbstractSqlDao.quietlyCloseConn(cnx);
    }
  }
예제 #2
0
  @Override
  protected final int execute(ExecuteContext ctx, ExecuteListener listener) throws SQLException {
    if (returning.isEmpty()) {
      return super.execute(ctx, listener);
    } else {
      int result = 1;
      ResultSet rs;
      switch (ctx.configuration().dialect()) {

          // SQLite can select _rowid_ after the insert
        case SQLITE:
          {
            listener.executeStart(ctx);
            result = ctx.statement().executeUpdate();
            listener.executeEnd(ctx);

            DSLContext create =
                DSL.using(ctx.connection(), SQLDialect.SQLITE, ctx.configuration().settings());
            returned =
                create
                    .select(returning)
                    .from(getInto())
                    .where(rowid().equal(rowid().getDataType().convert(create.lastID())))
                    .fetchInto(getInto());

            return result;
          }

          // Sybase can select @@identity after the insert
          // TODO [#832] Fix this. This might be a driver issue. JDBC
          // Generated keys don't work with jconn3, but they seem to work
          // with jTDS (which is used for Sybase ASE integration)
        case CUBRID:
        case SYBASE:
          {
            listener.executeStart(ctx);
            result = ctx.statement().executeUpdate();
            listener.executeEnd(ctx);

            selectReturning(ctx.configuration(), create(ctx.configuration()).lastID());
            return result;
          }

          // Some dialects can only retrieve "identity" (AUTO_INCREMENT) values
          // Additional values have to be fetched explicitly
          // [#1260] TODO CUBRID supports this, but there's a JDBC bug
        case ASE:
        case DERBY:
        case H2:
        case INGRES:
        case MYSQL:
        case SQLSERVER:
          {
            listener.executeStart(ctx);
            result = ctx.statement().executeUpdate();
            listener.executeEnd(ctx);

            rs = ctx.statement().getGeneratedKeys();

            try {
              List<Object> list = new ArrayList<Object>();

              // Some JDBC drivers seem to illegally return null
              // from getGeneratedKeys() sometimes
              if (rs != null) {
                while (rs.next()) {
                  list.add(rs.getObject(1));
                }
              }

              selectReturning(ctx.configuration(), list.toArray());
              return result;
            } finally {
              JDBCUtils.safeClose(rs);
            }
          }

          // Firebird and Postgres can execute the INSERT .. RETURNING
          // clause like a select clause. JDBC support is not implemented
          // in the Postgres JDBC driver
        case FIREBIRD:
        case POSTGRES:
          {
            listener.executeStart(ctx);
            rs = ctx.statement().executeQuery();
            listener.executeEnd(ctx);

            break;
          }

          // These dialects have full JDBC support
        case DB2:
        case HSQLDB:
        case ORACLE:
        default:
          {
            listener.executeStart(ctx);
            result = ctx.statement().executeUpdate();
            listener.executeEnd(ctx);

            rs = ctx.statement().getGeneratedKeys();
            break;
          }
      }

      ExecuteContext ctx2 = new DefaultExecuteContext(ctx.configuration());
      ExecuteListener listener2 = new ExecuteListeners(ctx2);

      ctx2.resultSet(rs);
      returned =
          new CursorImpl<R>(ctx2, listener2, fieldArray(returning), null, true, false)
              .fetch()
              .into(getInto());
      return result;
    }
  }
예제 #3
0
 @Override
 public final void close() {
   JDBCUtils.safeClose(rs);
   rs = null;
   isClosed = true;
 }