From 3059931d369358a8600c0f291c5321375f612f53 Mon Sep 17 00:00:00 2001 From: Rogiel Date: Thu, 15 Dec 2011 22:57:54 -0200 Subject: [PATCH] Implements bulk and transactioned inserts, updates and deletes --- .../service/database/AbstractDAO.java | 18 ++ .../database/AbstractJDBCDatabaseService.java | 300 ++++++++++++++---- .../service/database/DataAccessObject.java | 34 +- .../java/com/l2jserver/util/ArrayUtils.java | 40 +++ .../com/l2jserver/util/ArrayUtilsTest.java | 41 +++ .../database/jdbc/JDBCCharacterDAO.java | 18 +- .../database/jdbc/JDBCCharacterFriendDAO.java | 16 +- .../database/jdbc/JDBCChatMessageDAO.java | 16 +- .../service/database/jdbc/JDBCClanDAO.java | 20 +- .../service/database/jdbc/JDBCItemDAO.java | 24 +- .../service/database/jdbc/JDBCNPCDAO.java | 18 +- .../orientdb/OrientDBCharacterDAO.java | 18 +- .../orientdb/OrientDBCharacterFriendDAO.java | 18 +- .../orientdb/OrientDBChatMessageDAO.java | 18 +- .../database/orientdb/OrientDBClanDAO.java | 18 +- .../service/game/item/ItemServiceImpl.java | 12 +- 16 files changed, 462 insertions(+), 167 deletions(-) create mode 100644 l2jserver2-common/src/main/java/com/l2jserver/util/ArrayUtils.java create mode 100644 l2jserver2-common/src/test/java/com/l2jserver/util/ArrayUtilsTest.java diff --git a/l2jserver2-common/src/main/java/com/l2jserver/service/database/AbstractDAO.java b/l2jserver2-common/src/main/java/com/l2jserver/service/database/AbstractDAO.java index 1c5469c3d..21e8ed265 100644 --- a/l2jserver2-common/src/main/java/com/l2jserver/service/database/AbstractDAO.java +++ b/l2jserver2-common/src/main/java/com/l2jserver/service/database/AbstractDAO.java @@ -71,6 +71,24 @@ public abstract class AbstractDAO, I extends ID> } } + @Override + @SuppressWarnings("unchecked") + public boolean insert(T object) { + return insertObjects(object) > 0; + } + + @Override + @SuppressWarnings("unchecked") + public boolean update(T object) { + return updateObjects(object) > 0; + } + + @Override + @SuppressWarnings("unchecked") + public boolean delete(T object) { + return deleteObjects(object) > 0; + } + @Override public Iterator iterator() { return new Iterator() { diff --git a/l2jserver2-common/src/main/java/com/l2jserver/service/database/AbstractJDBCDatabaseService.java b/l2jserver2-common/src/main/java/com/l2jserver/service/database/AbstractJDBCDatabaseService.java index 32f5c6ed5..734293758 100644 --- a/l2jserver2-common/src/main/java/com/l2jserver/service/database/AbstractJDBCDatabaseService.java +++ b/l2jserver2-common/src/main/java/com/l2jserver/service/database/AbstractJDBCDatabaseService.java @@ -454,7 +454,6 @@ public abstract class AbstractJDBCDatabaseService extends AbstractService *
    *
  • INSERT INTO
  • *
  • UPDATE
  • - *
  • DELETE FROM
  • *
* * @author Rogiel @@ -501,45 +500,64 @@ public abstract class AbstractJDBCDatabaseService extends AbstractService Preconditions.checkNotNull(conn, "conn"); log.debug("Starting INSERT/UPDATE query execution"); + try { + conn.setAutoCommit(false); - int rows = 0; - while (iterator.hasNext()) { - final T object = iterator.next(); final String queryString = query(); - log.debug("Preparing statement for {}: {}", object, queryString); + log.debug("Preparing statement for {}", queryString); final PreparedStatement st = conn.prepareStatement(queryString, Statement.RETURN_GENERATED_KEYS); + try { + int rows = 0; + while (iterator.hasNext()) { + final T object = iterator.next(); - log.debug("Parametizing statement {} with {}", st, object); - this.parametize(st, object); + log.debug("Parametizing statement {} with {}", st, + object); + this.parametize(st, object); - log.debug("Sending query to database for {}", object); - rows = st.executeUpdate(); - log.debug("Query inserted or updated {} rows for {}", rows, - object); + log.debug("Sending query to database for {}", object); + rows += st.executeUpdate(); + log.debug("Query inserted or updated {} rows for {}", + rows, object); - // update object desire --it has been realized - if (object instanceof Model && rows > 0) { - log.debug("Updating Model ObjectDesire to NONE"); - ((Model) object).setObjectDesire(ObjectDesire.NONE); + // update object desire --it has been realized + if (object instanceof Model && rows > 0) { + log.debug("Updating Model ObjectDesire to NONE"); + ((Model) object) + .setObjectDesire(ObjectDesire.NONE); - final Mapper> mapper = keyMapper(); - if (mapper == null) - continue; - final ResultSet rs = st.getGeneratedKeys(); - log.debug("Mapping generated keys with {} using {}", - mapper, rs); - while (rs.next()) { - final ID generatedID = mapper.map(rs); - log.debug("Generated ID for {} is {}", object, - generatedID); - ((Model>) object).setID(generatedID); - mapper.map(rs); + final Mapper> mapper = keyMapper(); + if (mapper == null) + continue; + final ResultSet rs = st.getGeneratedKeys(); + try { + log.debug( + "Mapping generated keys with {} using {}", + mapper, rs); + while (rs.next()) { + final ID generatedID = mapper.map(rs); + log.debug("Generated ID for {} is {}", + object, generatedID); + ((Model>) object).setID(generatedID); + mapper.map(rs); + } + } finally { + rs.close(); + } + } } + return rows; + } finally { + st.close(); } + } catch (SQLException e) { + conn.rollback(); + throw e; + } finally { + conn.setAutoCommit(true); } - return rows; } /** @@ -573,6 +591,143 @@ public abstract class AbstractJDBCDatabaseService extends AbstractService } } + /** + * This query is used for the following statements: + *
    + *
  • DELETE FROM
  • + *
+ * + * @author Rogiel + * + * @param + * the query return type + */ + public static abstract class DeleteQuery implements Query { + /** + * The logger + */ + private final Logger log = LoggerFactory.getLogger(DeleteQuery.class); + + /** + * The {@link DatabaseService} + */ + private final AbstractJDBCDatabaseService database; + /** + * The iterator + */ + private final Iterator iterator; + + /** + * Creates a new query for objects + * + * @param database + * the {@link DatabaseService} + * @param objects + * the object list + */ + @SafeVarargs + public DeleteQuery(AbstractJDBCDatabaseService database, T... objects) { + this(database, new ArrayIterator(objects)); + } + + /** + * Create a new query for objects in iterator + * + * @param database + * the {@link DatabaseService} + * @param iterator + * the object iterator + */ + public DeleteQuery(AbstractJDBCDatabaseService database, + Iterator iterator) { + this.iterator = iterator; + this.database = database; + } + + @Override + public Integer query(Connection conn) throws SQLException { + Preconditions.checkNotNull(conn, "conn"); + + log.debug("Starting DELETE query execution"); + try { + conn.setAutoCommit(false); + + final String queryString = query(); + + log.debug("Preparing statement for {}", queryString); + final PreparedStatement st = conn.prepareStatement(queryString); + + try { + int rows = 0; + while (iterator.hasNext()) { + final T object = iterator.next(); + + log.debug("Parametizing statement {} with {}", st, + object); + this.parametize(st, object); + + log.debug("Sending query to database for {}", object); + rows = st.executeUpdate(); + log.debug("Query deleted {} rows for {}", rows, object); + + dispose(object); + if (object instanceof Model) { + database.removeCache(((Model) object) + .getObjectDesire()); + } + } + conn.commit(); + return rows; + } finally { + st.close(); + } + } catch (SQLException e) { + conn.rollback(); + throw e; + } finally { + conn.setAutoCommit(true); + } + } + + /** + * Creates the prepared query for execution + * + * @return the prepared query + */ + protected abstract String query(); + + /** + * Set the parameters for in statement for object + * + * @param st + * the prepared statement + * @param object + * the object + * @throws SQLException + * if any SQL error occur + */ + protected abstract void parametize(PreparedStatement st, T object) + throws SQLException; + + /** + * Disposes all object related resources, such as IDs. + * + * @param object + * the object that was been deleted + */ + protected abstract void dispose(T object); + + /** + * Return the key mapper. Can be null if no generated keys are used or + * are not important. + * + * @return the key mapper + */ + protected Mapper> keyMapper() { + return null; + } + } + /** * An select query that returns a list of objects of type T * @@ -597,31 +752,38 @@ public abstract class AbstractJDBCDatabaseService extends AbstractService final String queryString = query(); log.debug("Preparing statement with {}", queryString); final PreparedStatement st = conn.prepareStatement(query()); + try { + log.debug("Parametizing statement {}", st); + parametize(st); - log.debug("Parametizing statement {}", st); - parametize(st); + log.debug("Sending query to database for {}", st); + st.execute(); - log.debug("Sending query to database for {}", st); - st.execute(); - - final List list = CollectionFactory.newList(); - final ResultSet rs = st.getResultSet(); - final Mapper mapper = mapper(); - log.debug("Database returned {}", rs); - while (rs.next()) { - log.debug("Mapping row with {}", mapper); - final T obj = mapper.map(rs); - if (obj == null) { - log.debug("Mapper {} returned a null row", mapper); - continue; + final List list = CollectionFactory.newList(); + final ResultSet rs = st.getResultSet(); + try { + final Mapper mapper = mapper(); + log.debug("Database returned {}", rs); + while (rs.next()) { + log.debug("Mapping row with {}", mapper); + final T obj = mapper.map(rs); + if (obj == null) { + log.debug("Mapper {} returned a null row", mapper); + continue; + } + if (obj instanceof Model) { + ((Model) obj).setObjectDesire(ObjectDesire.NONE); + } + log.debug("Mapper {} returned {}", mapper, obj); + list.add(obj); + } + return list; + } finally { + rs.close(); } - if (obj instanceof Model) { - ((Model) obj).setObjectDesire(ObjectDesire.NONE); - } - log.debug("Mapper {} returned {}", mapper, obj); - list.add(obj); + } finally { + st.close(); } - return list; } /** @@ -679,26 +841,34 @@ public abstract class AbstractJDBCDatabaseService extends AbstractService final String queryString = query(); log.debug("Preparing statement with {}", queryString); final PreparedStatement st = conn.prepareStatement(query()); + try { + log.debug("Parametizing statement {}", st); + parametize(st); - log.debug("Parametizing statement {}", st); - parametize(st); + log.debug("Sending query to database for {}", st); + st.execute(); - log.debug("Sending query to database for {}", st); - st.execute(); - - final ResultSet rs = st.getResultSet(); - final Mapper mapper = mapper(); - log.debug("Database returned {}", rs); - while (rs.next()) { - log.debug("Mapping row {} with {}", rs, mapper); - final T object = mapper.map(rs); - if (object instanceof Model) { - ((Model) object).setObjectDesire(ObjectDesire.NONE); + final ResultSet rs = st.getResultSet(); + try { + final Mapper mapper = mapper(); + log.debug("Database returned {}", rs); + while (rs.next()) { + log.debug("Mapping row {} with {}", rs, mapper); + final T object = mapper.map(rs); + if (object instanceof Model) { + ((Model) object) + .setObjectDesire(ObjectDesire.NONE); + } + log.debug("Mapper {} returned {}", mapper, object); + return object; + } + return null; + } finally { + rs.close(); } - log.debug("Mapper {} returned {}", mapper, object); - return object; + } finally { + st.close(); } - return null; } /** diff --git a/l2jserver2-common/src/main/java/com/l2jserver/service/database/DataAccessObject.java b/l2jserver2-common/src/main/java/com/l2jserver/service/database/DataAccessObject.java index eba533b0b..b891f2193 100644 --- a/l2jserver2-common/src/main/java/com/l2jserver/service/database/DataAccessObject.java +++ b/l2jserver2-common/src/main/java/com/l2jserver/service/database/DataAccessObject.java @@ -21,7 +21,6 @@ import java.util.Iterator; import com.l2jserver.model.Model; import com.l2jserver.model.id.ID; -import com.l2jserver.service.cache.IgnoreCaching; /** * The Data Access Object interface used used to retrieve, save and remove @@ -63,7 +62,6 @@ public interface DataAccessObject, I extends ID> extends * * @return the list containing all {@link ID} objects */ - @IgnoreCaching Collection selectIDs(); /** @@ -75,7 +73,6 @@ public interface DataAccessObject, I extends ID> extends * @return true if the row was inserted or updated * @see DataAccessObject#save(Model, boolean) */ - @IgnoreCaching boolean save(O object); /** @@ -88,7 +85,6 @@ public interface DataAccessObject, I extends ID> extends * will force an save, even if the object has not changed * @return true if the row was inserted or updated */ - @IgnoreCaching boolean save(O object, boolean force); /** @@ -98,9 +94,17 @@ public interface DataAccessObject, I extends ID> extends * the object * @return true if the row was inserted */ - @IgnoreCaching boolean insert(O object); + /** + * Inserts several instances in the database using a transaction (if possible). + * + * @param objects + * the objects + * @return the number of inserted rows + */ + int insertObjects(@SuppressWarnings("unchecked") O... objects); + /** * Updates the instance in the database. * @@ -108,9 +112,17 @@ public interface DataAccessObject, I extends ID> extends * the object * @return true if the row was updated */ - @IgnoreCaching boolean update(O object); + /** + * Updates several instances in the database using a transaction (if possible). + * + * @param objects + * the objects + * @return the number of updated rows + */ + int updateObjects(@SuppressWarnings("unchecked") O... objects); + /** * Deletes the instance in the database. * @@ -118,6 +130,14 @@ public interface DataAccessObject, I extends ID> extends * the object * @return true if the row was deleted */ - @IgnoreCaching boolean delete(O object); + + /** + * Deletes several instances in the database using an transaction (if possible). + * + * @param objects + * the objects + * @return the numver of deleted rows + */ + int deleteObjects(@SuppressWarnings("unchecked") O... objects); } diff --git a/l2jserver2-common/src/main/java/com/l2jserver/util/ArrayUtils.java b/l2jserver2-common/src/main/java/com/l2jserver/util/ArrayUtils.java new file mode 100644 index 000000000..bb28c3e48 --- /dev/null +++ b/l2jserver2-common/src/main/java/com/l2jserver/util/ArrayUtils.java @@ -0,0 +1,40 @@ +/* + * This file is part of l2jserver2 . + * + * l2jserver2 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. + * + * l2jserver2 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 l2jserver2. If not, see . + */ +package com.l2jserver.util; + +import java.util.Arrays; +import java.util.List; + +import com.l2jserver.util.factory.CollectionFactory; + +/** + * @author Rogiel + * + */ +public class ArrayUtils { + @SafeVarargs + @SuppressWarnings("unchecked") + public final static T[] copyArrayExcept(T[] array, T... except) { + final List values = CollectionFactory.newList(); + for (final T item : array) { + if (Arrays.binarySearch(except, item) < 0) { + values.add(item); + } + } + return (T[]) values.toArray(); + } +} diff --git a/l2jserver2-common/src/test/java/com/l2jserver/util/ArrayUtilsTest.java b/l2jserver2-common/src/test/java/com/l2jserver/util/ArrayUtilsTest.java new file mode 100644 index 000000000..b16506dc7 --- /dev/null +++ b/l2jserver2-common/src/test/java/com/l2jserver/util/ArrayUtilsTest.java @@ -0,0 +1,41 @@ +/* + * This file is part of l2jserver2 . + * + * l2jserver2 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. + * + * l2jserver2 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 l2jserver2. If not, see . + */ +package com.l2jserver.util; + +import java.util.Arrays; + +import junit.framework.Assert; + +import org.junit.Test; + +/** + * @author Rogiel + * + */ +public class ArrayUtilsTest extends ArrayUtils { + @Test + public void testCopyArrayExcept() { + final String str1 = "one"; + final String str2 = "two"; + final String str3 = "three"; + + String[] arr = new String[] { str1, str2, str3 }; + + Assert.assertTrue(Arrays.equals(new String[] { str1, str3 }, + ArrayUtils.copyArrayExcept(arr, str2))); + } +} diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCCharacterDAO.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCCharacterDAO.java index 75dd4234b..2bb1f8e23 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCCharacterDAO.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCCharacterDAO.java @@ -296,8 +296,8 @@ public abstract class JDBCCharacterDAO extends } @Override - public boolean insert(L2Character character) { - return database.query(new InsertUpdateQuery(character) { + public int insertObjects(L2Character... characters) { + return database.query(new InsertUpdateQuery(characters) { @Override protected String query() { return "INSERT INTO `" + TABLE + "` (`" + CHAR_ID + "`,`" @@ -349,12 +349,12 @@ public abstract class JDBCCharacterDAO extends st.setString(i++, appearance.getHairColor().name()); st.setString(i++, appearance.getFace().name()); } - }) > 0; + }); } @Override - public boolean update(L2Character character) { - return database.query(new InsertUpdateQuery(character) { + public int updateObjects(L2Character... characters) { + return database.query(new InsertUpdateQuery(characters) { @Override protected String query() { return "UPDATE `" + TABLE + "` SET `" + ACCOUNT_ID + "` = ?,`" @@ -411,12 +411,12 @@ public abstract class JDBCCharacterDAO extends // WHERE st.setInt(i++, character.getID().getID()); } - }) > 0; + }); } @Override - public boolean delete(L2Character character) { - return database.query(new InsertUpdateQuery(character) { + public int deleteObjects(L2Character... characters) { + return database.query(new InsertUpdateQuery(characters) { @Override protected String query() { return "DELETE FROM `" + TABLE + "` WHERE `" + CHAR_ID @@ -428,6 +428,6 @@ public abstract class JDBCCharacterDAO extends L2Character character) throws SQLException { st.setInt(1, character.getID().getID()); } - }) > 0; + }); } } diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCCharacterFriendDAO.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCCharacterFriendDAO.java index d37f01ee5..5321b402c 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCCharacterFriendDAO.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCCharacterFriendDAO.java @@ -168,8 +168,8 @@ public abstract class JDBCCharacterFriendDAO extends } @Override - public boolean insert(CharacterFriend friend) { - return database.query(new InsertUpdateQuery(friend) { + public int insertObjects(CharacterFriend... friends) { + return database.query(new InsertUpdateQuery(friends) { @Override protected String query() { return "INSERT INTO `" + TABLE + "` (`" + CHAR_ID + "`,`" @@ -182,19 +182,19 @@ public abstract class JDBCCharacterFriendDAO extends st.setInt(1, friend.getCharacterID().getID()); st.setInt(2, friend.getFriendID().getID()); } - }) > 0; + }); } @Override - public boolean update(CharacterFriend friend) { + public int updateObjects(CharacterFriend... friends) { // it is not possible update friend objects, because they are only a ID // pair and IDs are immutable - return false; + return 0; } @Override - public boolean delete(CharacterFriend friend) { - return database.query(new InsertUpdateQuery(friend) { + public int deleteObjects(CharacterFriend... friends) { + return database.query(new InsertUpdateQuery(friends) { @Override protected String query() { return "DELETE FROM `" + TABLE + "` WHERE `" + CHAR_ID @@ -207,7 +207,7 @@ public abstract class JDBCCharacterFriendDAO extends st.setInt(1, friend.getCharacterID().getID()); st.setInt(2, friend.getFriendID().getID()); } - }) > 0; + }); } @Override diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCChatMessageDAO.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCChatMessageDAO.java index 5ef890917..8c235e11a 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCChatMessageDAO.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCChatMessageDAO.java @@ -169,8 +169,8 @@ public abstract class JDBCChatMessageDAO extends } @Override - public boolean insert(ChatMessage message) { - return database.query(new InsertUpdateQuery(message) { + public int insertObjects(ChatMessage... messages) { + return database.query(new InsertUpdateQuery(messages) { @Override protected String query() { return "INSERT INTO `" + TABLE + "` (`" + TYPE + "`,`" @@ -200,18 +200,18 @@ public abstract class JDBCChatMessageDAO extends protected Mapper keyMapper() { return primaryKeyMapper; } - }) > 0; + }); } @Override - public boolean update(ChatMessage message) { + public int updateObjects(ChatMessage... messages) { // cannot update chat message logs - return false; + return 0; } @Override - public boolean delete(ChatMessage message) { - return database.query(new InsertUpdateQuery(message) { + public int deleteObjects(ChatMessage... messages) { + return database.query(new InsertUpdateQuery(messages) { @Override protected String query() { return "DELETE FROM `" + TABLE + "` WHERE `" + MESSAGE_ID @@ -223,6 +223,6 @@ public abstract class JDBCChatMessageDAO extends throws SQLException { st.setInt(1, message.getID().getID()); } - }) > 0; + }); } } diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCClanDAO.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCClanDAO.java index be8bcd7d0..ad7ed9598 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCClanDAO.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCClanDAO.java @@ -29,12 +29,12 @@ import com.l2jserver.model.id.object.ClanID; import com.l2jserver.model.id.object.provider.CharacterIDProvider; import com.l2jserver.model.id.object.provider.ClanIDProvider; import com.l2jserver.model.world.Clan; -import com.l2jserver.service.database.DatabaseService; import com.l2jserver.service.database.AbstractJDBCDatabaseService.CachedMapper; import com.l2jserver.service.database.AbstractJDBCDatabaseService.InsertUpdateQuery; import com.l2jserver.service.database.AbstractJDBCDatabaseService.Mapper; import com.l2jserver.service.database.AbstractJDBCDatabaseService.SelectListQuery; import com.l2jserver.service.database.AbstractJDBCDatabaseService.SelectSingleQuery; +import com.l2jserver.service.database.DatabaseService; /** * {@link CharacterDAO} implementation for JDBC @@ -137,8 +137,8 @@ public abstract class JDBCClanDAO extends AbstractJDBCDAO } @Override - public boolean insert(Clan clan) { - return database.query(new InsertUpdateQuery(clan) { + public int insertObjects(Clan... clans) { + return database.query(new InsertUpdateQuery(clans) { @Override protected String query() { return "INSERT INTO `" + TABLE + "` (`" + CLAN_ID @@ -150,18 +150,18 @@ public abstract class JDBCClanDAO extends AbstractJDBCDAO throws SQLException { st.setInt(1, clan.getID().getID()); } - }) > 0; + }); } @Override - public boolean update(Clan clan) { - // TODO Auto-generated method stub - return false; + public int updateObjects(Clan... clans) { + // TODO implement clan update + return 0; } @Override - public boolean delete(Clan clan) { - return database.query(new InsertUpdateQuery(clan) { + public int deleteObjects(Clan... clans) { + return database.query(new InsertUpdateQuery(clans) { @Override protected String query() { return "DELETE FROM `" + TABLE + "` WHERE `" + CLAN_ID @@ -173,6 +173,6 @@ public abstract class JDBCClanDAO extends AbstractJDBCDAO throws SQLException { st.setInt(1, clan.getID().getID()); } - }) > 0; + }); } } diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCItemDAO.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCItemDAO.java index cbed4d037..832cc7006 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCItemDAO.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCItemDAO.java @@ -40,6 +40,7 @@ import com.l2jserver.model.world.character.CharacterInventory; import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll; import com.l2jserver.model.world.character.CharacterInventory.ItemLocation; import com.l2jserver.service.database.AbstractJDBCDatabaseService.CachedMapper; +import com.l2jserver.service.database.AbstractJDBCDatabaseService.DeleteQuery; import com.l2jserver.service.database.AbstractJDBCDatabaseService.InsertUpdateQuery; import com.l2jserver.service.database.AbstractJDBCDatabaseService.Mapper; import com.l2jserver.service.database.AbstractJDBCDatabaseService.SelectListQuery; @@ -239,8 +240,8 @@ public abstract class JDBCItemDAO extends AbstractJDBCDAO } @Override - public boolean insert(Item item) { - return database.query(new InsertUpdateQuery(item) { + public int insertObjects(Item... items) { + return database.query(new InsertUpdateQuery(items) { @Override protected String query() { return "INSERT INTO `" + TABLE + "` (`" + ITEM_ID + "`,`" @@ -276,12 +277,12 @@ public abstract class JDBCItemDAO extends AbstractJDBCDAO st.setNull(i++, Types.INTEGER); } } - }) > 0; + }); } @Override - public boolean update(Item item) { - return database.query(new InsertUpdateQuery(item) { + public int updateObjects(Item... items) { + return database.query(new InsertUpdateQuery(items) { @Override protected String query() { return "UPDATE `" + TABLE + "` SET `" + CHAR_ID + "` = ?,`" @@ -318,12 +319,12 @@ public abstract class JDBCItemDAO extends AbstractJDBCDAO // WHERE st.setInt(i++, item.getID().getID()); } - }) > 0; + }); } @Override - public boolean delete(Item item) { - return database.query(new InsertUpdateQuery(item) { + public int deleteObjects(Item... items) { + return database.query(new DeleteQuery(database, items) { @Override protected String query() { return "DELETE FROM `" + TABLE + "` WHERE `" + ITEM_ID @@ -335,6 +336,11 @@ public abstract class JDBCItemDAO extends AbstractJDBCDAO throws SQLException { st.setInt(1, item.getID().getID()); } - }) > 0; + + @Override + protected void dispose(Item object) { + idFactory.destroy(object.getID()); + } + }); } } diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCNPCDAO.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCNPCDAO.java index 5d049697c..1090650c6 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCNPCDAO.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCNPCDAO.java @@ -217,8 +217,8 @@ public abstract class JDBCNPCDAO extends AbstractJDBCDAO implements } @Override - public boolean insert(NPC npc) { - return database.query(new InsertUpdateQuery(npc) { + public int insertObjects(NPC... npcs) { + return database.query(new InsertUpdateQuery(npcs) { @Override protected String query() { return "INSERT INTO `" + TABLE + "` (`" + NPC_ID + "`,`" @@ -246,12 +246,12 @@ public abstract class JDBCNPCDAO extends AbstractJDBCDAO implements st.setLong(i++, npc.getRespawnInterval()); } - }) > 0; + }); } @Override - public boolean update(NPC npc) { - return database.query(new InsertUpdateQuery(npc) { + public int updateObjects(NPC... npcs) { + return database.query(new InsertUpdateQuery(npcs) { @Override protected String query() { return "UPDATE `" + TABLE + "` SET `" + NPC_TEMPLATE_ID @@ -282,12 +282,12 @@ public abstract class JDBCNPCDAO extends AbstractJDBCDAO implements // WHERE st.setInt(i++, npc.getID().getID()); } - }) > 0; + }); } @Override - public boolean delete(NPC npc) { - return database.query(new InsertUpdateQuery(npc) { + public int deleteObjects(NPC... npcs) { + return database.query(new InsertUpdateQuery(npcs) { @Override protected String query() { return "DELETE FROM `" + TABLE + "` WHERE `" + NPC_ID + "` = ?"; @@ -298,6 +298,6 @@ public abstract class JDBCNPCDAO extends AbstractJDBCDAO implements throws SQLException { st.setInt(1, npc.getID().getID()); } - }) > 0; + }); } } diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBCharacterDAO.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBCharacterDAO.java index 2cdefd866..caef191fa 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBCharacterDAO.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBCharacterDAO.java @@ -248,8 +248,8 @@ public class OrientDBCharacterDAO extends } @Override - public boolean insert(L2Character object) { - return database.query(new InsertUpdateQuery(object) { + public int insertObjects(L2Character... objects) { + return database.query(new InsertUpdateQuery(objects) { @Override protected ONativeSynchQuery> createQuery( ODatabaseDocumentTx database, L2Character object) { @@ -301,12 +301,12 @@ public class OrientDBCharacterDAO extends return document; } - }) != 0; + }); } @Override - public boolean update(final L2Character character) { - return database.query(new InsertUpdateQuery(character) { + public int updateObjects(final L2Character... characters) { + return database.query(new InsertUpdateQuery(characters) { @Override protected ONativeSynchQuery> createQuery( ODatabaseDocumentTx database, final L2Character character) { @@ -368,12 +368,12 @@ public class OrientDBCharacterDAO extends throws SQLException { return null; } - }) != 0; + }); } @Override - public boolean delete(L2Character object) { - return database.query(new InsertUpdateQuery(object) { + public int deleteObjects(L2Character... objects) { + return database.query(new InsertUpdateQuery(objects) { @Override protected ONativeSynchQuery> createQuery( ODatabaseDocumentTx database, final L2Character character) { @@ -403,7 +403,7 @@ public class OrientDBCharacterDAO extends throws SQLException { return null; } - }) != 0; + }); } @Override diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBCharacterFriendDAO.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBCharacterFriendDAO.java index 9f12d254d..0b426fab4 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBCharacterFriendDAO.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBCharacterFriendDAO.java @@ -45,7 +45,7 @@ import com.orientechnologies.orient.core.record.impl.ODocument; * * @author Rogiel */ -public abstract class OrientDBCharacterFriendDAO extends +public class OrientDBCharacterFriendDAO extends AbstractOrientDBDAO implements CharacterFriendDAO { /** @@ -194,8 +194,8 @@ public abstract class OrientDBCharacterFriendDAO extends } @Override - public boolean insert(CharacterFriend friend) { - return database.query(new InsertUpdateQuery(friend) { + public int insertObjects(CharacterFriend... friends) { + return database.query(new InsertUpdateQuery(friends) { @Override protected ONativeSynchQuery> createQuery( ODatabaseDocumentTx database, CharacterFriend object) { @@ -215,19 +215,19 @@ public abstract class OrientDBCharacterFriendDAO extends document.field(CHAR_ID_FRIEND, friend.getFriendID()); return document; } - }) > 0; + }); } @Override - public boolean update(CharacterFriend friend) { + public int updateObjects(CharacterFriend... friends) { // it is not possible update friend objects, because they are only a ID // pair and IDs are immutable - return false; + return 0; } @Override - public boolean delete(CharacterFriend friend) { - return database.query(new InsertUpdateQuery(friend) { + public int deleteObjects(CharacterFriend... friends) { + return database.query(new InsertUpdateQuery(friends) { @Override protected ONativeSynchQuery> createQuery( ODatabaseDocumentTx database, final CharacterFriend friend) { @@ -259,7 +259,7 @@ public abstract class OrientDBCharacterFriendDAO extends CharacterFriend friend) throws SQLException { return null; } - }) > 0; + }); } @Override diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBChatMessageDAO.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBChatMessageDAO.java index 1eb0ebc93..e01c0ea06 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBChatMessageDAO.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBChatMessageDAO.java @@ -45,7 +45,7 @@ import com.orientechnologies.orient.core.record.impl.ODocument; * * @author Rogiel */ -public abstract class OrientDBChatMessageDAO extends +public class OrientDBChatMessageDAO extends AbstractOrientDBDAO implements ChatMessageDAO { /** @@ -180,8 +180,8 @@ public abstract class OrientDBChatMessageDAO extends } @Override - public boolean insert(ChatMessage message) { - return database.query(new InsertUpdateQuery(message) { + public int insertObjects(ChatMessage... messages) { + return database.query(new InsertUpdateQuery(messages) { @Override protected ONativeSynchQuery> createQuery( ODatabaseDocumentTx database, ChatMessage object) { @@ -212,18 +212,18 @@ public abstract class OrientDBChatMessageDAO extends return document; } - }) > 0; + }); } @Override - public boolean update(ChatMessage message) { + public int updateObjects(ChatMessage... messages) { // cannot update chat message logs - return false; + return 0; } @Override - public boolean delete(ChatMessage message) { - return database.query(new InsertUpdateQuery(message) { + public int deleteObjects(ChatMessage... messages) { + return database.query(new InsertUpdateQuery(messages) { @Override protected ONativeSynchQuery> createQuery( ODatabaseDocumentTx database, final ChatMessage message) { @@ -254,6 +254,6 @@ public abstract class OrientDBChatMessageDAO extends // TODO Auto-generated method stub return null; } - }) > 0; + }); } } diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBClanDAO.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBClanDAO.java index 852b80d9b..db91d7b86 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBClanDAO.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/orientdb/OrientDBClanDAO.java @@ -44,7 +44,7 @@ import com.orientechnologies.orient.core.record.impl.ODocument; * * @author Rogiel */ -public abstract class OrientDBClanDAO extends AbstractOrientDBDAO +public class OrientDBClanDAO extends AbstractOrientDBDAO implements ClanDAO { /** * The {@link ChatMessageID} factory @@ -159,8 +159,8 @@ public abstract class OrientDBClanDAO extends AbstractOrientDBDAO } @Override - public boolean insert(Clan clan) { - return database.query(new InsertUpdateQuery(clan) { + public int insertObjects(Clan... clans) { + return database.query(new InsertUpdateQuery(clans) { @Override protected ONativeSynchQuery> createQuery( ODatabaseDocumentTx database, Clan object) { @@ -180,18 +180,18 @@ public abstract class OrientDBClanDAO extends AbstractOrientDBDAO document.field(CHAR_ID_LEADER, clan.getLeaderID().getID()); return document; } - }) > 0; + }); } @Override - public boolean update(Clan clan) { + public int updateObjects(Clan... clans) { // cannot update chat message logs - return false; + return 0; } @Override - public boolean delete(Clan clan) { - return database.query(new InsertUpdateQuery(clan) { + public int deleteObjects(Clan... clans) { + return database.query(new InsertUpdateQuery(clans) { @Override protected ONativeSynchQuery> createQuery( ODatabaseDocumentTx database, final Clan clan) { @@ -221,6 +221,6 @@ public abstract class OrientDBClanDAO extends AbstractOrientDBDAO // TODO Auto-generated method stub return null; } - }) > 0; + }); } } diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/item/ItemServiceImpl.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/item/ItemServiceImpl.java index e067b73ab..8883185a5 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/item/ItemServiceImpl.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/item/ItemServiceImpl.java @@ -44,6 +44,7 @@ import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException; import com.l2jserver.service.game.spawn.SpawnService; import com.l2jserver.service.game.world.WorldService; import com.l2jserver.service.game.world.event.WorldEventDispatcher; +import com.l2jserver.util.ArrayUtils; import com.l2jserver.util.geometry.Point3D; /** @@ -177,12 +178,8 @@ public class ItemServiceImpl extends AbstractService implements ItemService { item = stack(stackItems); Item[] removedItems = character.getInventory().remove( stackItems); - for (final Item removeItem : removedItems) { - if (!removeItem.equals(item)) { - itemDao.delete(removeItem); - itemIdProvider.destroy(removeItem.getID()); - } - } + Item[] databaseDeleteItems = ArrayUtils.copyArrayExcept(removedItems, item); + itemDao.deleteObjects(databaseDeleteItems); character.getInventory().add(item); } catch (NonStackableItemsServiceException e) { character.getInventory().add(item); @@ -195,6 +192,9 @@ public class ItemServiceImpl extends AbstractService implements ItemService { this.items.remove(item); itemDao.save(item); + if (!item.equals(originalItem)) { + itemDao.save(originalItem); + } spawnService.unspawn(originalItem); eventDispatcher.dispatch(new ItemPickUpEvent(character, originalItem, item));