/**
* OrbisGIS is a java GIS application dedicated to research in GIScience.
* OrbisGIS is developed by the GIS group of the DECIDE team of the
* Lab-STICC CNRS laboratory, see <http://www.lab-sticc.fr/>.
*
* The GIS group of the DECIDE team is located at :
*
* Laboratoire Lab-STICC – CNRS UMR 6285
* Equipe DECIDE
* UNIVERSITÉ DE BRETAGNE-SUD
* Institut Universitaire de Technologie de Vannes
* 8, Rue Montaigne - BP 561 56017 Vannes Cedex
*
* OrbisGIS is distributed under GPL 3 license.
*
* Copyright (C) 2007-2014 CNRS (IRSTV FR CNRS 2488)
* Copyright (C) 2015-2017 CNRS (Lab-STICC UMR CNRS 6285)
*
* This file is part of OrbisGIS.
*
* OrbisGIS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* OrbisGIS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* OrbisGIS. If not, see <http://www.gnu.org/licenses/>.
*
* For more information, please consult: <http://www.orbisgis.org/>
* or contact directly:
* info_at_ orbisgis.org
*/
package org.orbisgis.corejdbc.internal;
import com.vividsolutions.jts.geom.Geometry;
import org.h2gis.utilities.TableLocation;
import org.orbisgis.corejdbc.DataManager;
import org.orbisgis.corejdbc.TableEditEvent;
import org.orbisgis.corejdbc.TableEditListener;
import org.orbisgis.corejdbc.ReversibleRowSet;
import org.orbisgis.commons.progress.ProgressMonitor;
import javax.sql.DataSource;
import javax.swing.event.TableModelEvent;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.NClob;
import java.sql.Ref;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Time;
import java.sql.Timestamp;
/**
* Implementation of {@link ReversibleRowSet}
* @author Nicolas Fortin
*/
public class ReversibleRowSetImpl extends ReadRowSetImpl implements ReversibleRowSet {
private DataManager manager;
private TableUndoableUpdate[] updateRow = null;
private TableUndoableInsert insertRow = null;
public ReversibleRowSetImpl(DataSource dataSource, DataManager manager) {
super(dataSource);
this.manager = manager;
}
@Override
public boolean absolute(int i) throws SQLException {
updateRow = null;
insertRow = null;
return super.absolute(i);
}
/**
* Initialize this row set
* @param location Table location
* @param pk_name Primary key name {@link ReadRowSetImpl#getPkName()}
* @param pm Progress monitor Progression of primary key caching
*/
public ReversibleRowSetImpl(DataSource dataSource, DataManager manager, TableLocation location, String pk_name, ProgressMonitor pm) throws SQLException {
super(dataSource);
this.manager = manager;
initialize(location, pk_name, pm);
}
@Override
public void addTableEditListener(String table, TableEditListener listener) {
manager.addTableEditListener(getTable(), listener);
}
/**
* Check if this RowSet is ready for update.
* @throws SQLException If this rowset has no exposed PK column.
*/
private void checkUpdate(int column) throws SQLException {
if(cachedColumnNames == null) {
cacheColumnNames();
}
if(pk_name.isEmpty() || !cachedColumnNames.containsKey(pk_name)) {
throw new SQLException(I18N.tr("Edition is disabled on table without single numeric primary key."));
}
//else if(cachedColumnNames.get(pk_name) == column) {
// throw new SQLException(I18N.tr("Can not edit primary key values"));
//}
}
@Override
protected void checkCurrentRow() throws SQLException {
if(insertRow != null) {
throw new SQLException(I18N.tr("On insert row"));
}
super.checkCurrentRow();
}
@Override
public void removeTableEditListener(String table, TableEditListener listener) {
manager.removeTableEditListener(getTable(), listener);
}
@Override
public void updateNull(int i) throws SQLException {
updateObject(i, null);
}
@Override
public void updateBoolean(int i, boolean b) throws SQLException {
updateObject(i, b);
}
@Override
public void updateByte(int i, byte b) throws SQLException {
updateObject(i, b);
}
@Override
public void updateShort(int i, short i2) throws SQLException {
updateShort(i, i2);
}
@Override
public void updateInt(int i, int i2) throws SQLException {
updateObject(i, i2);
}
@Override
public void updateLong(int i, long l) throws SQLException {
updateObject(i, l);
}
@Override
public void updateFloat(int i, float v) throws SQLException {
updateObject(i, v);
}
@Override
public void updateDouble(int i, double v) throws SQLException {
updateObject(i, v);
}
@Override
public void updateBigDecimal(int i, BigDecimal bigDecimal) throws SQLException {
updateObject(i, bigDecimal);
}
@Override
public void updateString(int i, String s) throws SQLException {
updateObject(i, s);
}
@Override
public void updateBytes(int i, byte[] bytes) throws SQLException {
updateObject(i, bytes);
}
@Override
public void updateDate(int i, Date date) throws SQLException {
updateObject(i, date);
}
@Override
public void updateTime(int i, Time time) throws SQLException {
updateObject(i, time);
}
@Override
public void updateTimestamp(int i, Timestamp timestamp) throws SQLException {
updateObject(i, timestamp);
}
@Override
public void updateAsciiStream(int i, InputStream inputStream, int i2) throws SQLException {
updateObject(i, inputStream);
}
@Override
public void updateBinaryStream(int i, InputStream inputStream, int i2) throws SQLException {
updateObject(i, inputStream);
}
@Override
public void updateCharacterStream(int i, Reader reader, int i2) throws SQLException {
updateObject(i, reader);
}
@Override
public void updateObject(int i, Object o, int i2) throws SQLException {
updateObject(i, o);
}
@Override
public void updateObject(int i, Object o) throws SQLException {
checkUpdate(i);
if(insertRow != null) {
insertRow.setValue(getColumnName(i), o);
} else {
if(updateRow == null) {
updateRow = new TableUndoableUpdate[getColumnCount()];
}
updateRow[i - 1] = new TableUndoableUpdate(manager,isH2, location, pk_name, getPk(), getColumnName(i), getObject(i), o, this);
}
}
@Override
public void updateNull(String s) throws SQLException {
updateNull(findColumn(s));
}
@Override
public void updateBoolean(String s, boolean b) throws SQLException {
updateBoolean(findColumn(s), b);
}
@Override
public void updateByte(String s, byte b) throws SQLException {
updateByte(findColumn(s), b);
}
@Override
public void updateShort(String s, short i) throws SQLException {
updateShort(findColumn(s), i);
}
@Override
public void updateInt(String s, int i) throws SQLException {
updateInt(findColumn(s), i);
}
@Override
public void updateLong(String s, long l) throws SQLException {
updateLong(findColumn(s), l);
}
@Override
public void updateFloat(String s, float v) throws SQLException {
updateFloat(findColumn(s), v);
}
@Override
public void updateDouble(String s, double v) throws SQLException {
updateDouble(findColumn(s), v);
}
@Override
public void updateBigDecimal(String s, BigDecimal bigDecimal) throws SQLException {
updateBigDecimal(findColumn(s), bigDecimal);
}
@Override
public void updateString(String s, String s2) throws SQLException {
updateString(findColumn(s), s2);
}
@Override
public void updateBytes(String s, byte[] bytes) throws SQLException {
updateBytes(findColumn(s), bytes);
}
@Override
public void updateDate(String s, Date date) throws SQLException {
updateDate(findColumn(s), date);
}
@Override
public void updateTime(String s, Time time) throws SQLException {
updateTime(findColumn(s), time);
}
@Override
public void updateTimestamp(String s, Timestamp timestamp) throws SQLException {
updateTimestamp(findColumn(s), timestamp);
}
@Override
public void updateAsciiStream(String s, InputStream inputStream, int i) throws SQLException {
updateAsciiStream(findColumn(s), inputStream, i);
}
@Override
public void updateBinaryStream(String s, InputStream inputStream, int i) throws SQLException {
updateBinaryStream(findColumn(s), inputStream, i);
}
@Override
public void updateCharacterStream(String s, Reader reader, int i) throws SQLException {
updateCharacterStream(findColumn(s), reader, i);
}
@Override
public void updateObject(String s, Object o, int i) throws SQLException {
updateObject(findColumn(s), o, i);
}
@Override
public void updateObject(String s, Object o) throws SQLException {
updateObject(findColumn(s), o);
}
@Override
public void insertRow() throws SQLException {
if(insertRow == null) {
throw new SQLException(I18N.tr("RowSet not moved to insert row"));
}
insertRow.redo(false);
cachedRowCount++;
manager.fireTableEditHappened(new TableEditEvent(location.toString(isH2), insertRow,
TableModelEvent.ALL_COLUMNS, insertRow.getPrimaryKey(), insertRow.getPrimaryKey(),
TableModelEvent.INSERT));
moveToInsertRow();
}
@Override
public void updateRow() throws SQLException {
if(insertRow != null) {
throw new SQLException("On insert row");
}
if(updateRow != null) {
int pkColumnId = cachedColumnNames.get(pk_name);
for(int updateColumn = 0; updateColumn < updateRow.length; updateColumn++) {
TableUndoableUpdate update = updateRow[updateColumn];
if(update != null && updateColumn != pkColumnId ) {
update.redo(false);
manager.fireTableEditHappened(new TableEditEvent(location.toString(isH2), update, updateColumn,
getPk(), getPk(), TableModelEvent.DELETE));
}
}
if(updateRow[pkColumnId] != null) {
TableUndoableUpdate update = updateRow[pkColumnId];
update.redo(false);
refreshRow();
updateRow = null;
manager.fireTableEditHappened(new TableEditEvent(location.toString(isH2), update, pkColumnId, getPk() ,
getPk() , TableModelEvent.DELETE));
} else {
updateRow = null;
cache.remove(rowId);
currentRow = null;
currentBatch.clear();
currentBatchId = -1;
}
}
}
@Override
public void deleteRow() throws SQLException {
checkCurrentRow();
TableUndoableDelete deleteEvt = new TableUndoableDelete(manager, location, pk_name, isH2);
for(int idColumn = 0; idColumn < currentRow.row.length; idColumn++) {
deleteEvt.setValue(getColumnLabel(idColumn + 1), currentRow.row[idColumn]);
}
deleteEvt.redo(false);
cachedRowCount--;
refreshRow();
manager.fireTableEditHappened(new TableEditEvent(location.toString(isH2), deleteEvt, TableModelEvent
.ALL_COLUMNS, deleteEvt.getPrimaryKey(), deleteEvt.getPrimaryKey(), TableModelEvent.DELETE));
}
@Override
public void cancelRowUpdates() throws SQLException {
updateRow = null;
insertRow = null;
}
@Override
public void moveToInsertRow() throws SQLException {
insertRow = new TableUndoableInsert(manager, location, pk_name, isH2);
}
@Override
public void moveToCurrentRow() throws SQLException {
cancelRowUpdates();
absolute((int)rowId);
}
@Override
public void updateRef(int i, Ref ref) throws SQLException {
updateObject(i, ref);
}
@Override
public void updateRef(String s, Ref ref) throws SQLException {
updateRef(findColumn(s), ref);
}
@Override
public void updateBlob(int i, Blob blob) throws SQLException {
updateObject(i, blob);
}
@Override
public void updateBlob(String s, Blob blob) throws SQLException {
updateBlob(findColumn(s), blob);
}
@Override
public void updateClob(int i, Clob clob) throws SQLException {
updateObject(i, clob);
}
@Override
public void updateClob(String s, Clob clob) throws SQLException {
updateClob(findColumn(s), clob);
}
@Override
public void updateArray(int i, Array array) throws SQLException {
updateObject(i, array);
}
@Override
public void updateArray(String s, Array array) throws SQLException {
updateArray(findColumn(s), array);
}
@Override
public void updateRowId(int i, RowId rowId) throws SQLException {
updateObject(i, rowId);
}
@Override
public void updateRowId(String s, RowId rowId) throws SQLException {
updateRowId(findColumn(s), rowId);
}
@Override
public void updateNString(int i, String s) throws SQLException {
updateObject(i, s);
}
@Override
public void updateNString(String s, String s2) throws SQLException {
updateNString(findColumn(s), s2);
}
@Override
public void updateNClob(int i, NClob nClob) throws SQLException {
updateObject(i, nClob);
}
@Override
public void updateNClob(String s, NClob nClob) throws SQLException {
updateNClob(findColumn(s), nClob);
}
@Override
public void updateSQLXML(int i, SQLXML sqlxml) throws SQLException {
updateObject(i, sqlxml);
}
@Override
public void updateSQLXML(String s, SQLXML sqlxml) throws SQLException {
updateSQLXML(findColumn(s), sqlxml);
}
@Override
public void updateNCharacterStream(int i, Reader reader, long l) throws SQLException {
updateObject(i, reader);
}
@Override
public void updateNCharacterStream(String s, Reader reader, long l) throws SQLException {
updateNCharacterStream(findColumn(s), reader, l);
}
@Override
public void updateAsciiStream(int i, InputStream inputStream, long l) throws SQLException {
updateObject(i, inputStream);
}
@Override
public void updateBinaryStream(int i, InputStream inputStream, long l) throws SQLException {
updateBinaryStream(i, inputStream);
}
@Override
public void updateCharacterStream(int i, Reader reader, long l) throws SQLException {
updateCharacterStream(i, reader);
}
@Override
public void updateAsciiStream(String s, InputStream inputStream, long l) throws SQLException {
updateAsciiStream(s, inputStream);
}
@Override
public void updateBinaryStream(String s, InputStream inputStream, long l) throws SQLException {
updateBinaryStream(s, inputStream);
}
@Override
public void updateCharacterStream(String s, Reader reader, long l) throws SQLException {
updateCharacterStream(s, reader);
}
@Override
public void updateBlob(int i, InputStream inputStream, long l) throws SQLException {
updateBlob(i, inputStream);
}
@Override
public void updateBlob(String s, InputStream inputStream, long l) throws SQLException {
updateBlob(s, inputStream);
}
@Override
public void updateClob(int i, Reader reader, long l) throws SQLException {
updateClob(i, reader);
}
@Override
public void updateClob(String s, Reader reader, long l) throws SQLException {
updateClob(s, reader);
}
@Override
public void updateNClob(int i, Reader reader, long l) throws SQLException {
updateNClob(i, reader);
}
@Override
public void updateNClob(String s, Reader reader, long l) throws SQLException {
updateNClob(s, reader);
}
@Override
public void updateNCharacterStream(int i, Reader reader) throws SQLException {
updateObject(i, reader);
}
@Override
public void updateNCharacterStream(String s, Reader reader) throws SQLException {
updateNCharacterStream(findColumn(s), reader);
}
@Override
public void updateAsciiStream(int i, InputStream inputStream) throws SQLException {
updateObject(i, inputStream);
}
@Override
public void updateBinaryStream(int i, InputStream inputStream) throws SQLException {
updateObject(i, inputStream);
}
@Override
public void updateCharacterStream(int i, Reader reader) throws SQLException {
updateObject(i, reader);
}
@Override
public void updateAsciiStream(String s, InputStream inputStream) throws SQLException {
updateAsciiStream(findColumn(s), inputStream);
}
@Override
public void updateBinaryStream(String s, InputStream inputStream) throws SQLException {
updateBinaryStream(findColumn(s), inputStream);
}
@Override
public void updateCharacterStream(String s, Reader reader) throws SQLException {
updateCharacterStream(findColumn(s), reader);
}
@Override
public void updateBlob(int i, InputStream inputStream) throws SQLException {
updateObject(i, inputStream);
}
@Override
public void updateBlob(String s, InputStream inputStream) throws SQLException {
updateBlob(findColumn(s), inputStream);
}
@Override
public void updateClob(int i, Reader reader) throws SQLException {
updateObject(i, reader);
}
@Override
public void updateClob(String s, Reader reader) throws SQLException {
updateClob(findColumn(s), reader);
}
@Override
public void updateNClob(int i, Reader reader) throws SQLException {
updateObject(i, reader);
}
@Override
public void updateNClob(String s, Reader reader) throws SQLException {
updateNClob(findColumn(s), reader);
}
@Override
public void updateGeometry(Geometry geometry) throws SQLException {
updateObject(getFirstGeometryFieldIndex(), geometry);
}
@Override
public void rollback() throws SQLException {
throw new UnsupportedOperationException("Autocommit is on");
}
@Override
public void rollback(Savepoint s) throws SQLException {
throw new UnsupportedOperationException("Autocommit is on");
}
}