package org.develnext.jphp.ext.sql.classes; import org.develnext.jphp.ext.sql.SqlExtension; import php.runtime.Memory; import php.runtime.annotation.Reflection; import php.runtime.annotation.Reflection.Abstract; import php.runtime.annotation.Reflection.Signature; import php.runtime.env.Environment; import php.runtime.ext.core.classes.stream.Stream; import php.runtime.ext.core.classes.time.WrapTime; import php.runtime.lang.BaseObject; import php.runtime.lang.ForeachIterator; import php.runtime.lang.spl.iterator.Iterator; import php.runtime.memory.BinaryMemory; import php.runtime.memory.LongMemory; import php.runtime.memory.ObjectMemory; import php.runtime.reflection.ClassEntity; import java.io.InputStream; import java.sql.*; @Abstract @Reflection.Name("SqlStatement") @Reflection.Namespace(SqlExtension.NS) public class PSqlStatement extends BaseObject implements Iterator { protected PreparedStatement statement; protected boolean valid = true; private ResultSet resultSet; public PSqlStatement(Environment env, PreparedStatement statement) { super(env); this.statement = statement; } public PSqlStatement(Environment env, ClassEntity clazz) { super(env, clazz); } @Signature public PSqlResult fetch(Environment env) throws SQLException { ResultSet resultSet = statement.executeQuery(); if (resultSet.next()) { return new PSqlResult(env, resultSet); } else { return null; } } @Signature public boolean execute(Environment env) throws SQLException { return statement.execute(); } @Signature public int update(Environment env) throws SQLException { return statement.executeUpdate(); } @Signature public Memory getLastInsertId(Environment env) throws SQLException { Memory keys = getGeneratedKeys(env); if (keys.instanceOf(PSqlResult.class)) { return keys.toObject(PSqlResult.class).getTyped(env, 0); } return Memory.NULL; } @Signature public Memory getGeneratedKeys(Environment env) throws SQLException { ResultSet keys = statement.getGeneratedKeys(); if (keys != null && keys.next()) { return ObjectMemory.valueOf(new PSqlResult(env, keys)); } return Memory.NULL; } @Signature public void bindBlob(Environment env, int index, Memory arg) throws SQLException { InputStream is = Stream.getInputStream(env, arg); try { statement.setBlob(index + 1, is); } finally { Stream.closeStream(env, is); } } @Signature public void bindDate(Environment env, int index, WrapTime time) throws SQLException { statement.setDate(index + 1, new Date(time.getDate().getTime()), time.getCalendar()); } @Signature public void bindTime(Environment env, int index, WrapTime time) throws SQLException { statement.setTime(index + 1, new Time(time.getDate().getTime()), time.getCalendar()); } @Signature public void bindTimestamp(Environment env, int index, Memory value) throws SQLException { if (value.instanceOf(WrapTime.class)) { WrapTime time = value.toObject(WrapTime.class); statement.setTimestamp(index + 1, new Timestamp(time.getDate().getTime()), time.getCalendar()); } else { statement.setTimestamp(index + 1, new Timestamp(value.toLong())); } } @Signature public void bind(Environment env, int index, Memory value) throws SQLException { if (value.instanceOf(WrapTime.class)) { WrapTime time = value.toObject(WrapTime.class); statement.setDate(index + 1, new Date(time.getDate().getTime()), time.getCalendar()); } else if (value.instanceOf(Stream.class)) { statement.setBlob(index + 1, Stream.getInputStream(env, value)); } else if (value.toValue() instanceof BinaryMemory) { statement.setBytes(index + 1, value.getBinaryBytes(env.getDefaultCharset())); } else { if (value.isNull()) { statement.setNull(index + 1, Types.NULL); } else { switch (value.getRealType()) { case INT: statement.setLong(index + 1, value.toLong()); break; case DOUBLE: statement.setDouble(index + 1, value.toDouble()); break; case BOOL: statement.setBoolean(index + 1, value.toBoolean()); break; default: statement.setString(index + 1, value.toString()); } } } } @Override public Memory current(Environment env, Memory... args) { return resultSet == null ? Memory.NULL : ObjectMemory.valueOf(new PSqlResult(env, resultSet)); } @Override public Memory key(Environment env, Memory... args) { try { return resultSet != null ? LongMemory.valueOf(resultSet.getRow() - 1) : Memory.NULL; } catch (SQLException e) { throw new WrapSqlException(env, e); } } @Override public Memory next(Environment env, Memory... args) { try { if (resultSet == null) { valid = false; } else { valid = resultSet.next(); } } catch (SQLException e) { throw new WrapSqlException(env, e); } return Memory.NULL; } @Override public Memory rewind(Environment env, Memory... args) { try { resultSet = statement.executeQuery(); if (resultSet != null) { valid = resultSet.next(); } else { valid = false; } } catch (SQLException e) { throw new WrapSqlException(env, e); } return Memory.NULL; } @Override public Memory valid(Environment env, Memory... args) { return valid && resultSet != null ? Memory.TRUE : Memory.FALSE; } @Override public ForeachIterator getNewIterator(Environment env, boolean getReferences, boolean getKeyReferences) { return ObjectMemory.valueOf(this).getNewIterator(env, getReferences, getKeyReferences); } @Override public ForeachIterator getNewIterator(Environment env) { return ObjectMemory.valueOf(this).getNewIterator(env); } }