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();
- }
- } finally {
- st.close();
- }
- }
-
- /**
- * 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
- * @throws SQLException
- * if any SQL error occur
- */
- protected void parametize(PreparedStatement st) throws SQLException {
- }
-
- /**
- * Return the mapper that will bind {@link ResultSet} objects into an
- * T object instance. The mapper will need to create the object
- * instance.
- *
- * Note : This method will be called for each row, an thus is a
- * good idea to create a new instance on each call!
- *
- * @return the mapper instance
- */
- protected abstract Mapper mapper();
- }
-
- /**
- * An select query that returns a single object of type T
- *
- * @author Rogiel
- *
- * @param
- * the query return type
- */
- public static abstract class SelectSingleQuery implements Query {
- /**
- * The logger
- */
- private final Logger log = LoggerFactory
- .getLogger(SelectSingleQuery.class);
-
- @Override
- public T query(Connection conn) throws SQLException {
- Preconditions.checkNotNull(conn, "conn");
-
- log.debug("Starting SELECT single query execution");
-
- 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("Sending query to database for {}", st);
- st.execute();
-
- 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();
- }
- } finally {
- st.close();
- }
- }
-
- /**
- * 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
- * @throws SQLException
- * if any SQL error occur
- */
- protected void parametize(PreparedStatement st) throws SQLException {
- }
-
- /**
- * Return the mapper that will bind {@link ResultSet} objects into an
- * T object instance. The mapper will need to create the object
- * instance.
- *
- * @return the mapper
- */
- protected abstract Mapper mapper();
- }
-
- /**
- * The {@link Mapper} maps an {@link ResultSet} into an object T
- *
- * @author Rogiel
- *
- * @param
- * the object type
- */
- public interface Mapper {
- /**
- * Map the result set value into an object.
- *
- * Note : it is required to call {@link ResultSet#next()}, since
- * it is called by the {@link Query}.
- *
- * @param rs
- * the result set
- * @return the created instance
- * @throws SQLException
- * if any SQL error occur
- */
- T map(ResultSet rs) throws SQLException;
- }
-
- /**
- * The cached mapper will try to lookup the result in the cache, before
- * create a new instance. If the instance is not found in the cache, then
- * the {@link Mapper} implementation is called to create the object. Note
- * that the ID, used for the cache lookup, will be reused. After creation,
- * the cache is updated.
- *
- * @author Rogiel
- *
- * @param
- * the object type
- * @param
- * the id type
- */
- public abstract static class CachedMapper, I extends ID>>
- implements Mapper {
- /**
- * The logger
- */
- private final Logger log = LoggerFactory
- .getLogger(SelectSingleQuery.class);
-
- /**
- * The database service instance
- */
- private final AbstractJDBCDatabaseService database;
-
- /**
- * The {@link ID} mapper
- */
- private final Mapper idMapper;
-
- /**
- * Creates a new instance
- *
- * @param database
- * the database service
- * @param idMapper
- * the {@link ID} {@link Mapper}
- */
- public CachedMapper(AbstractJDBCDatabaseService database,
- Mapper idMapper) {
- this.database = database;
- this.idMapper = idMapper;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public final T map(ResultSet rs) throws SQLException {
- log.debug("Mapping row {} ID with {}", rs, idMapper);
- final I id = idMapper.map(rs);
- Preconditions.checkNotNull(id, "id");
-
- log.debug("ID={}, locating cached object", id);
-
- if (database.hasCachedObject(id))
- return (T) database.getCachedObject(id);
-
- log.debug("Cached object not found, creating...");
-
- final T object = map(id, rs);
- if (object != null)
- database.updateCache(id, object);
- log.debug("Object {} created", object);
- return object;
- }
-
- /**
- * Maps an uncached object. Once mapping is complete, it will be added
- * to the cache.
- *
- * @param id
- * the object id
- * @param rs
- * the jdbc result set
- * @return the created object
- * @throws SQLException
- * if any SQL error occur
- */
- protected abstract T map(I id, ResultSet rs) throws SQLException;
- }
-}
diff --git a/l2jserver2-common/src/main/java/com/l2jserver/service/database/AbstractOrientDatabaseService.java b/l2jserver2-common/src/main/java/com/l2jserver/service/database/AbstractOrientDatabaseService.java
deleted file mode 100644
index aacc9ee84..000000000
--- a/l2jserver2-common/src/main/java/com/l2jserver/service/database/AbstractOrientDatabaseService.java
+++ /dev/null
@@ -1,702 +0,0 @@
-/*
- * 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.service.database;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-import com.google.inject.Inject;
-import com.l2jserver.model.Model;
-import com.l2jserver.model.Model.ObjectDesire;
-import com.l2jserver.model.id.ID;
-import com.l2jserver.model.id.object.allocator.IDAllocator;
-import com.l2jserver.service.AbstractService;
-import com.l2jserver.service.ServiceStartException;
-import com.l2jserver.service.ServiceStopException;
-import com.l2jserver.service.cache.Cache;
-import com.l2jserver.service.cache.CacheService;
-import com.l2jserver.service.configuration.ConfigurationService;
-import com.l2jserver.service.configuration.XMLConfigurationService.ConfigurationXPath;
-import com.l2jserver.service.core.threading.AbstractTask;
-import com.l2jserver.service.core.threading.AsyncFuture;
-import com.l2jserver.service.core.threading.ScheduledAsyncFuture;
-import com.l2jserver.service.core.threading.ThreadService;
-import com.l2jserver.util.ArrayIterator;
-import com.l2jserver.util.factory.CollectionFactory;
-import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
-import com.orientechnologies.orient.core.query.nativ.ONativeSynchQuery;
-import com.orientechnologies.orient.core.query.nativ.OQueryContextNative;
-import com.orientechnologies.orient.core.record.impl.ODocument;
-
-/**
- * This is an implementation of {@link DatabaseService} that provides an layer
- * to JDBC.
- *
- * Internal specification The {@link Query} object
- *
- * If you wish to implement a new {@link DataAccessObject} you should try not
- * use {@link Query} object directly because it only provides low level access
- * to the JDBC architecture. Instead, you could use an specialized class, like
- * {@link InsertUpdateQuery}, {@link SelectListQuery} or
- * {@link SelectSingleQuery}. If you do need low level access, feel free to use
- * the {@link Query} class directly.
- *
- * The {@link Mapper} object
- *
- * The {@link Mapper} object maps an JDBC {@link ResultSet} into an Java
- * {@link Object}. All {@link Model} objects support {@link CachedMapper} that
- * will cache result based on its {@link ID} and always use the same object with
- * the same {@link ID}.
- *
- * @author Rogiel
- */
-public abstract class AbstractOrientDatabaseService extends AbstractService
- implements DatabaseService {
- /**
- * The configuration object
- */
- private final OrientDatabaseConfiguration config;
- /**
- * The logger
- */
- private final Logger log = LoggerFactory
- .getLogger(AbstractOrientDatabaseService.class);
-
- /**
- * The cache service
- */
- private final CacheService cacheService;
- /**
- * The thread service
- */
- private final ThreadService threadService;
- /**
- * The {@link DAOResolver} instance
- */
- private final DAOResolver daoResolver;
-
- private ODatabaseDocumentTx database;
-
- /**
- * An cache object
- */
- private Cache> objectCache;
- /**
- * Future for the auto-save task. Each object that has changed is auto saved
- * every 1 minute.
- */
- private ScheduledAsyncFuture autoSaveFuture;
-
- /**
- * Configuration interface for {@link AbstractOrientDatabaseService}.
- *
- * @author Rogiel
- */
- public interface OrientDatabaseConfiguration extends DatabaseConfiguration {
- /**
- * @return the orientdb url
- */
- @ConfigurationPropertyGetter(defaultValue = "file:data/database")
- @ConfigurationXPath("/configuration/services/database/orientdb/url")
- String getUrl();
-
- /**
- * @param url
- * the new orientdb url
- */
- @ConfigurationPropertySetter
- @ConfigurationXPath("/configuration/services/database/orientdb/url")
- void setUrl(String url);
-
- /**
- * @return the orientdb database username
- */
- @ConfigurationPropertyGetter(defaultValue = "l2j")
- @ConfigurationXPath("/configuration/services/database/orientdb/username")
- String getUsername();
-
- /**
- * @param username
- * the orientdb database username
- */
- @ConfigurationPropertySetter
- @ConfigurationXPath("/configuration/services/database/orientdb/username")
- void setUsername(String username);
-
- /**
- * @return the orientdb database password
- */
- @ConfigurationPropertyGetter(defaultValue = "changeme")
- @ConfigurationXPath("/configuration/services/database/orientdb/password")
- String getPassword();
-
- /**
- * @param password
- * the jdbc database password
- */
- @ConfigurationPropertySetter
- @ConfigurationXPath("/configuration/services/database/jdbc/password")
- void setPassword(String password);
- }
-
- /**
- * @param configService
- * the configuration service
- * @param cacheService
- * the cache service
- * @param threadService
- * the thread service
- * @param daoResolver
- * the {@link DataAccessObject DAO} resolver
- */
- @Inject
- public AbstractOrientDatabaseService(ConfigurationService configService,
- CacheService cacheService, ThreadService threadService,
- DAOResolver daoResolver) {
- config = configService.get(OrientDatabaseConfiguration.class);
- this.cacheService = cacheService;
- this.threadService = threadService;
- this.daoResolver = daoResolver;
- }
-
- @Override
- protected void doStart() throws ServiceStartException {
- database = new ODatabaseDocumentTx(config.getUrl());
- if (!database.exists()) {
- database.create();
- } else {
- database.open(config.getUsername(), config.getPassword());
- }
-
- // cache must be large enough for all world objects, to avoid
- // duplication... this would endanger non-persistent states
- objectCache = cacheService.createEternalCache("database-service",
- IDAllocator.ALLOCABLE_IDS);
-
- // start the auto save task
- autoSaveFuture = threadService.async(60, TimeUnit.SECONDS, 60,
- new Runnable() {
- @Override
- public void run() {
- log.debug("Auto save task started");
- int objects = 0;
- for (final Model> object : objectCache) {
- @SuppressWarnings("unchecked")
- final DataAccessObject, ?> dao = daoResolver
- .getDAO(object.getClass());
- if (dao.save(object) > 0) {
- objects++;
- }
- }
- log.info(
- "{} objects have been saved by the auto save task",
- objects);
- }
- });
- }
-
- @Override
- public int transaction(TransactionExecutor executor) {
- return executor.perform();
- }
-
- @Override
- public AsyncFuture transactionAsync(
- final TransactionExecutor executor) {
- return threadService.async(new AbstractTask() {
- @Override
- public Integer call() throws Exception {
- return transaction(executor);
- }
- });
- }
-
- /**
- * Executes an query in the database.
- *
- * @param
- * the query return type
- * @param query
- * the query
- * @return an instance of T
- */
- public T query(Query query) {
- Preconditions.checkNotNull(query, "query");
- log.debug("Executing query {} with {}", query, database);
- try {
- return query.query(database);
- } catch (SQLException e) {
- log.error("Database error", e);
- return null;
- }
- }
-
- /**
- * Checks for the cached version of the object
- *
- * @param id
- * the object ID
- * @return the cached version, if any
- */
- public Object getCachedObject(Object id) {
- Preconditions.checkNotNull(id, "id");
- log.debug("Fetching cached object {}", id);
- return objectCache.get(id);
- }
-
- /**
- * Checks for the cached version of the object
- *
- * @param id
- * the object ID
- * @return true if has an cached version,
- */
- public boolean hasCachedObject(Object id) {
- Preconditions.checkNotNull(id, "id");
- log.debug("Locating cached object {}", id);
- return objectCache.contains(id);
- }
-
- /**
- * Updates an cache object
- *
- * @param id
- * the cache key
- * @param value
- * the model value
- */
- public void updateCache(ID> id, Model> value) {
- Preconditions.checkNotNull(id, "key");
- Preconditions.checkNotNull(value, "value");
- log.debug("Updating cached object {} with {}", id, value);
- objectCache.put(id, value);
- }
-
- /**
- * Removes an cached object
- *
- * @param id
- * the object id
- */
- public void removeCache(Object id) {
- Preconditions.checkNotNull(id, "key");
- log.debug("Removing cached object {}", id);
- objectCache.remove(id);
- }
-
- @Override
- protected void doStop() throws ServiceStopException {
- autoSaveFuture.cancel(true);
- autoSaveFuture = null;
- cacheService.dispose(objectCache);
- objectCache = null;
- database.close();
- database = null;
- }
-
- /**
- * The query interface. The query will receive an connection an will be
- * executed. The can return return a value if required.
- *
- * @author Rogiel
- *
- * @param
- * the return type
- */
- public interface Query {
- /**
- * Execute the query in conn
- *
- * @param database
- * the database connection
- * @return the query return value
- * @throws SQLException
- * if any SQL error occur
- */
- R query(ODatabaseDocumentTx database) throws SQLException;
- }
-
- /**
- * This query is used for the following statements:
- *
- * INSERT INTO
- * UPDATE
- * DELETE FROM
- *
- *
- * @author Rogiel
- *
- * @param
- * the query return type
- */
- public static abstract class InsertUpdateQuery implements Query {
- /**
- * The logger
- */
- private final Logger log = LoggerFactory
- .getLogger(InsertUpdateQuery.class);
-
- /**
- * The iterator
- */
- private final Iterator iterator;
-
- /**
- * Creates a new query for objects
- *
- * @param objects
- * the object list
- */
- @SafeVarargs
- public InsertUpdateQuery(T... objects) {
- this(new ArrayIterator(objects));
- }
-
- /**
- * Create a new query for objects in iterator
- *
- * @param iterator
- * the object iterator
- */
- public InsertUpdateQuery(Iterator iterator) {
- this.iterator = iterator;
- }
-
- @Override
- public Integer query(ODatabaseDocumentTx database) throws SQLException {
- Preconditions.checkNotNull(database, "database");
-
- log.debug("Starting INSERT/UPDATE query execution");
-
- int rows = 0;
- while (iterator.hasNext()) {
- final T object = iterator.next();
- final ONativeSynchQuery query = createQuery(
- database, object);
- final ODocument document;
- if (query != null) {
- List docs = database.query(query);
- if (docs.size() >= 1) {
- document = update(docs.get(0), object);
- } else {
- continue;
- }
- } else {
- document = insert(new ODocument(), object);
- }
- if (document != null)
- database.save(document);
- rows++;
- }
- return rows;
- }
-
- /**
- * Creates the prepared query for execution
- *
- * @param database
- * the database
- * @param object
- * the object that is being updated
- *
- * @return the prepared query. If null is returned a
- * insert query will be performed.
- */
- protected abstract ONativeSynchQuery createQuery(
- ODatabaseDocumentTx database, T object);
-
- /**
- * Set the parameters in document for object . The
- * object can be removed calling {@link ODocument#delete()} and
- * returning null
- *
- * @param document
- * the document
- * @param object
- * the object
- * @return the updated document. Can be null
- * @throws SQLException
- * if any SQL error occur
- */
- protected abstract ODocument update(ODocument document, T object)
- throws SQLException;
-
- /**
- * Set the parameters for in statement for object
- *
- * @param document
- * the document
- * @param object
- * the object
- * @return the filled document
- * @throws SQLException
- * if any SQL error occur
- */
- protected abstract ODocument insert(ODocument document, T object)
- throws SQLException;
-
- /**
- * Return the key mapper. Can be null if no generated keys are used or
- * are not important.
- *
- * @return the key mapper
- */
- protected Mapper extends ID>> keyMapper() {
- return null;
- }
- }
-
- /**
- * An select query that returns a list of objects of type T
- *
- * @author Rogiel
- *
- * @param
- * the query return type
- */
- public static abstract class SelectListQuery implements Query> {
- /**
- * The logger
- */
- private final Logger log = LoggerFactory
- .getLogger(SelectListQuery.class);
-
- @Override
- public List query(ODatabaseDocumentTx database) throws SQLException {
- Preconditions.checkNotNull(database, "database");
-
- log.debug("Starting SELECT List> query execution");
-
- List result = database.query(createQuery(database));
- final List list = CollectionFactory.newList();
- final Mapper mapper = mapper();
- log.debug("Database returned {}", result);
- for (final ODocument document : result) {
- log.debug("Mapping row with {}", mapper);
- final T obj = mapper.map(document);
- 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;
- }
-
- /**
- * Creates the prepared query for execution
- *
- * @param database
- * the database
- *
- * @return the prepared query
- */
- protected abstract ONativeSynchQuery createQuery(
- ODatabaseDocumentTx database);
-
- /**
- * Return the mapper that will bind {@link ResultSet} objects into an
- * T object instance. The mapper will need to create the object
- * instance.
- *
- * Note : This method will be called for each row, an thus is a
- * good idea to create a new instance on each call!
- *
- * @return the mapper instance
- */
- protected abstract Mapper mapper();
- }
-
- /**
- * An select query that returns a single object of type T
- *
- * @author Rogiel
- *
- * @param
- * the query return type
- */
- public static abstract class SelectSingleQuery implements Query {
- /**
- * The logger
- */
- private final Logger log = LoggerFactory
- .getLogger(SelectSingleQuery.class);
-
- @Override
- public T query(ODatabaseDocumentTx database) throws SQLException {
- Preconditions.checkNotNull(database, "database");
-
- log.debug("Starting SELECT single query execution");
-
- List result = database.query(createQuery(database));
- final Mapper mapper = mapper();
- log.debug("Database returned {}", result);
- for (final ODocument document : result) {
- log.debug("Mapping row with {}", mapper);
- final T obj = mapper.map(document);
- 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);
- return obj;
- }
- return null;
- }
-
- /**
- * Creates the prepared query for execution
- *
- * @param database
- * the database
- *
- * @return the prepared query
- */
- protected abstract ONativeSynchQuery createQuery(
- ODatabaseDocumentTx database);
-
- /**
- * Return the mapper that will bind {@link ResultSet} objects into an
- * T object instance. The mapper will need to create the object
- * instance.
- *
- * Note : This method will be called for each row, an thus is a
- * good idea to create a new instance on each call!
- *
- * @return the mapper instance
- */
- protected abstract Mapper mapper();
- }
-
- /**
- * The {@link Mapper} maps an {@link ResultSet} into an object T
- *
- * @author Rogiel
- *
- * @param
- * the object type
- */
- public interface Mapper {
- /**
- * Map the result set value into an object.
- *
- * Note : it is required to call {@link ResultSet#next()}, since
- * it is called by the {@link Query}.
- *
- * @param document
- * the resulted document
- * @return the created instance
- * @throws SQLException
- * if any SQL error occur
- */
- T map(ODocument document) throws SQLException;
- }
-
- /**
- * The cached mapper will try to lookup the result in the cache, before
- * create a new instance. If the instance is not found in the cache, then
- * the {@link Mapper} implementation is called to create the object. Note
- * that the ID, used for the cache lookup, will be reused. After creation,
- * the cache is updated.
- *
- * @author Rogiel
- *
- * @param
- * the object type
- * @param
- * the id type
- */
- public abstract static class CachedMapper, I extends ID>>
- implements Mapper {
- /**
- * The logger
- */
- private final Logger log = LoggerFactory
- .getLogger(SelectSingleQuery.class);
-
- /**
- * The database service instance
- */
- private final AbstractOrientDatabaseService database;
-
- /**
- * The {@link ID} mapper
- */
- private final Mapper idMapper;
-
- /**
- * Creates a new instance
- *
- * @param database
- * the database service
- * @param idMapper
- * the {@link ID} {@link Mapper}
- */
- public CachedMapper(AbstractOrientDatabaseService database,
- Mapper idMapper) {
- this.database = database;
- this.idMapper = idMapper;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public final T map(ODocument document) throws SQLException {
- log.debug("Mapping row {} ID with {}", document, idMapper);
- final I id = idMapper.map(document);
- Preconditions.checkNotNull(id, "id");
-
- log.debug("ID={}, locating cached object", id);
-
- if (database.hasCachedObject(id))
- return (T) database.getCachedObject(id);
-
- log.debug("Cached object not found, creating...");
-
- final T object = map(id, document);
- if (object != null)
- database.updateCache(id, object);
- log.debug("Object {} created", object);
- return object;
- }
-
- /**
- * Maps an uncached object. Once mapping is complete, it will be added
- * to the cache.
- *
- * @param id
- * the object id
- * @param document
- * the document result
- * @return the created object
- * @throws SQLException
- * if any SQL error occur
- */
- protected abstract T map(I id, ODocument document) throws SQLException;
- }
-}
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 43dce29f4..c8e07fd2c 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
@@ -180,8 +180,9 @@ public interface DataAccessObject, I extends ID>> extends
*
* @param object
* the object
+ * @return the number of inserted rows
*/
- void insert(O object);
+ int insert(O object);
/**
* Inserts several instances in the database using a transaction (if
@@ -210,8 +211,9 @@ public interface DataAccessObject, I extends ID>> extends
*
* @param object
* the object
+ * @return the number of updated rows
*/
- void update(O object);
+ int update(O object);
/**
* Updates several instances in the database using a transaction (if
diff --git a/l2jserver2-common/src/main/java/com/l2jserver/service/database/orientdb/AbstractOrientDBDAO.java b/l2jserver2-common/src/main/java/com/l2jserver/service/database/DatabaseMappingException.java
similarity index 51%
rename from l2jserver2-common/src/main/java/com/l2jserver/service/database/orientdb/AbstractOrientDBDAO.java
rename to l2jserver2-common/src/main/java/com/l2jserver/service/database/DatabaseMappingException.java
index 199cac91a..46d02cf82 100644
--- a/l2jserver2-common/src/main/java/com/l2jserver/service/database/orientdb/AbstractOrientDBDAO.java
+++ b/l2jserver2-common/src/main/java/com/l2jserver/service/database/DatabaseMappingException.java
@@ -14,31 +14,40 @@
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see .
*/
-package com.l2jserver.service.database.orientdb;
-
-import com.l2jserver.model.Model;
-import com.l2jserver.model.id.ID;
-import com.l2jserver.service.database.AbstractDAO;
-import com.l2jserver.service.database.AbstractOrientDatabaseService;
-import com.l2jserver.service.database.DatabaseService;
+package com.l2jserver.service.database;
/**
* @author Rogiel
- * @param
- * the model type
- * @param
- * the id type
*/
-public abstract class AbstractOrientDBDAO, I extends ID>>
- extends AbstractDAO {
- protected final AbstractOrientDatabaseService database;
+public class DatabaseMappingException extends DatabaseException {
+ private static final long serialVersionUID = 1L;
+
+ public DatabaseMappingException() {
+ super();
+ }
/**
- * @param database
- * the database instance
+ * @param message
+ * the message
+ * @param cause
+ * the root cause
*/
- protected AbstractOrientDBDAO(DatabaseService database) {
- super(database);
- this.database = (AbstractOrientDatabaseService) database;
+ public DatabaseMappingException(String message, Throwable cause) {
+ }
+
+ /**
+ * @param message
+ * the message
+ */
+ public DatabaseMappingException(String message) {
+ super(message);
+ }
+
+ /**
+ * @param cause
+ * the root cause
+ */
+ public DatabaseMappingException(Throwable cause) {
+ super(cause);
}
}
diff --git a/l2jserver2-common/src/main/java/com/l2jserver/service/database/DatabaseService.java b/l2jserver2-common/src/main/java/com/l2jserver/service/database/DatabaseService.java
index 4f77a19ef..427582b7e 100644
--- a/l2jserver2-common/src/main/java/com/l2jserver/service/database/DatabaseService.java
+++ b/l2jserver2-common/src/main/java/com/l2jserver/service/database/DatabaseService.java
@@ -16,6 +16,8 @@
*/
package com.l2jserver.service.database;
+import com.l2jserver.model.Model;
+import com.l2jserver.model.id.ID;
import com.l2jserver.service.Service;
import com.l2jserver.service.ServiceConfiguration;
import com.l2jserver.service.configuration.Configuration;
@@ -98,4 +100,60 @@ public interface DatabaseService extends Service {
*/
int perform();
}
+
+ /**
+ * Checks for the cached version of the object
+ *
+ * @param
+ * the {@link ID} type
+ * @param
+ * the {@link Model} type
+ *
+ * @param id
+ * the object ID
+ * @return the cached version, if any
+ */
+ , O extends Model>> Object getCachedObject(I id);
+
+ /**
+ * Checks for the cached version of the object
+ *
+ * @param
+ * the {@link ID} type
+ * @param
+ * the {@link Model} type
+ *
+ * @param id
+ * the object ID
+ * @return true if has an cached version,
+ */
+ , O extends Model>> boolean hasCachedObject(I id);
+
+ /**
+ * Updates an cache object
+ *
+ * @param
+ * the {@link ID} type
+ * @param
+ * the {@link Model} type
+ *
+ * @param id
+ * the cache key
+ * @param value
+ * the model value
+ */
+ , O extends Model>> void updateCache(I id, O value);
+
+ /**
+ * Removes an cached object
+ *
+ * @param
+ * the {@link ID} type
+ * @param
+ * the {@link Model} type
+ *
+ * @param id
+ * the object id
+ */
+ , O extends Model>> void removeCache(I id);
}
diff --git a/l2jserver2-common/src/main/java/com/l2jserver/service/database/dao/DatabaseRow.java b/l2jserver2-common/src/main/java/com/l2jserver/service/database/dao/DatabaseRow.java
new file mode 100644
index 000000000..21a6992db
--- /dev/null
+++ b/l2jserver2-common/src/main/java/com/l2jserver/service/database/dao/DatabaseRow.java
@@ -0,0 +1,30 @@
+/*
+ * 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.service.database.dao;
+
+import com.mysema.query.types.Path;
+
+/**
+ * Database column used to read data
+ *
+ * @author Rogiel
+ */
+public interface DatabaseRow {
+ T get(Path path);
+
+ boolean isNull(Path path);
+}
diff --git a/l2jserver2-common/src/main/java/com/l2jserver/service/database/dao/Mapper.java b/l2jserver2-common/src/main/java/com/l2jserver/service/database/dao/Mapper.java
new file mode 100644
index 000000000..67cf91f10
--- /dev/null
+++ b/l2jserver2-common/src/main/java/com/l2jserver/service/database/dao/Mapper.java
@@ -0,0 +1,30 @@
+/*
+ * 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.service.database.dao;
+
+import com.mysema.query.sql.RelationalPathBase;
+
+/**
+ * @author Rogiel
+ * @param
+ * the object type returned by this mapper
+ * @param
+ * the entity type
+ */
+public interface Mapper> {
+ O map(E entity, DatabaseRow row);
+}
diff --git a/l2jserver2-common/src/main/java/com/l2jserver/service/database/jdbc/AbstractJDBCDAO.java b/l2jserver2-common/src/main/java/com/l2jserver/service/database/jdbc/AbstractJDBCDAO.java
index dc92dab77..51aa36bff 100644
--- a/l2jserver2-common/src/main/java/com/l2jserver/service/database/jdbc/AbstractJDBCDAO.java
+++ b/l2jserver2-common/src/main/java/com/l2jserver/service/database/jdbc/AbstractJDBCDAO.java
@@ -21,7 +21,6 @@ import com.l2jserver.model.Model;
import com.l2jserver.model.id.ID;
import com.l2jserver.service.database.AbstractDAO;
import com.l2jserver.service.database.DatabaseService;
-import com.l2jserver.service.database.AbstractJDBCDatabaseService;
/**
* {@link AbstractDAO} for JDBC DAO implementation
diff --git a/l2jserver2-common/src/main/java/com/l2jserver/service/database/jdbc/AbstractJDBCDatabaseService.java b/l2jserver2-common/src/main/java/com/l2jserver/service/database/jdbc/AbstractJDBCDatabaseService.java
new file mode 100644
index 000000000..35692c748
--- /dev/null
+++ b/l2jserver2-common/src/main/java/com/l2jserver/service/database/jdbc/AbstractJDBCDatabaseService.java
@@ -0,0 +1,848 @@
+/*
+ * 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.service.database.jdbc;
+
+import java.lang.reflect.InvocationTargetException;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Provider;
+import javax.sql.DataSource;
+
+import org.apache.commons.dbcp.ConnectionFactory;
+import org.apache.commons.dbcp.DriverManagerConnectionFactory;
+import org.apache.commons.dbcp.PoolableConnectionFactory;
+import org.apache.commons.dbcp.PoolingDataSource;
+import org.apache.commons.pool.impl.GenericObjectPool;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterators;
+import com.google.inject.Inject;
+import com.l2jserver.model.Model;
+import com.l2jserver.model.Model.ObjectDesire;
+import com.l2jserver.model.id.ID;
+import com.l2jserver.model.id.object.allocator.IDAllocator;
+import com.l2jserver.service.AbstractService;
+import com.l2jserver.service.ServiceStartException;
+import com.l2jserver.service.ServiceStopException;
+import com.l2jserver.service.cache.Cache;
+import com.l2jserver.service.cache.CacheService;
+import com.l2jserver.service.configuration.ConfigurationService;
+import com.l2jserver.service.configuration.XMLConfigurationService.ConfigurationXPath;
+import com.l2jserver.service.core.threading.AbstractTask;
+import com.l2jserver.service.core.threading.AsyncFuture;
+import com.l2jserver.service.core.threading.ScheduledAsyncFuture;
+import com.l2jserver.service.core.threading.ThreadService;
+import com.l2jserver.service.database.DAOResolver;
+import com.l2jserver.service.database.DataAccessObject;
+import com.l2jserver.service.database.DatabaseException;
+import com.l2jserver.service.database.DatabaseService;
+import com.l2jserver.service.database.dao.DatabaseRow;
+import com.l2jserver.service.database.dao.Mapper;
+import com.l2jserver.util.factory.CollectionFactory;
+import com.mysema.query.sql.AbstractSQLQuery;
+import com.mysema.query.sql.Configuration;
+import com.mysema.query.sql.RelationalPathBase;
+import com.mysema.query.sql.SQLQueryFactory;
+import com.mysema.query.sql.SQLTemplates;
+import com.mysema.query.sql.dml.SQLDeleteClause;
+import com.mysema.query.sql.dml.SQLInsertClause;
+import com.mysema.query.sql.dml.SQLUpdateClause;
+import com.mysema.query.sql.types.Type;
+import com.mysema.query.types.Path;
+
+/**
+ * This is an implementation of {@link DatabaseService} that provides an layer
+ * to JDBC.
+ *
+ * Internal specification The {@link Query} object
+ *
+ * If you wish to implement a new {@link DataAccessObject} you should try not
+ * use {@link Query} object directly because it only provides low level access
+ * to the JDBC architecture. Instead, you could use an specialized class, like
+ * {@link InsertQuery}, {@link SelectListQuery} or {@link SelectSingleQuery}. If
+ * you do need low level access, feel free to use the {@link Query} class
+ * directly.
+ *
+ * The {@link Mapper} object
+ *
+ * The {@link Mapper} object maps an JDBC {@link DatabaseRow} into an Java
+ * {@link Object}.
+ *
+ * @author Rogiel
+ */
+public abstract class AbstractJDBCDatabaseService extends AbstractService
+ implements DatabaseService {
+ /**
+ * The configuration object
+ */
+ private final JDBCDatabaseConfiguration config;
+ /**
+ * The logger
+ */
+ private final Logger log = LoggerFactory
+ .getLogger(AbstractJDBCDatabaseService.class);
+
+ /**
+ * The cache service
+ */
+ private final CacheService cacheService;
+ /**
+ * The thread service
+ */
+ private final ThreadService threadService;
+ /**
+ * The {@link DAOResolver} instance
+ */
+ private final DAOResolver daoResolver;
+
+ /**
+ * The database connection pool
+ */
+ private GenericObjectPool connectionPool;
+ /**
+ * The dayabase connection factory
+ */
+ private ConnectionFactory connectionFactory;
+ /**
+ * The poolable connection factory
+ */
+ @SuppressWarnings("unused")
+ private PoolableConnectionFactory poolableConnectionFactory;
+ /**
+ * The connection {@link DataSource}.
+ */
+ private PoolingDataSource dataSource;
+
+ /**
+ * An cache object
+ */
+ private Cache, Model>> objectCache;
+ /**
+ * Future for the auto-save task. Each object that has changed is auto saved
+ * every 1 minute.
+ */
+ private ScheduledAsyncFuture autoSaveFuture;
+
+ /**
+ * The connection used inside a transaction from multiple DAOs.
+ */
+ private ThreadLocal transactionalConnection = new ThreadLocal<>();
+ /**
+ * The {@link Type} that will be mapped by the querydsl.
+ */
+ private final Type>[] sqlTypes;
+
+ private SQLTemplates queryTemplates;
+ private Configuration queryConfig;
+
+ /**
+ * Configuration interface for {@link AbstractJDBCDatabaseService}.
+ *
+ * @author Rogiel
+ */
+ public interface JDBCDatabaseConfiguration extends DatabaseConfiguration {
+ /**
+ * @return the jdbc url
+ */
+ @ConfigurationPropertyGetter(defaultValue = "jdbc:mysql://localhost/l2jserver2")
+ @ConfigurationXPath("/configuration/services/database/jdbc/url")
+ String getJdbcUrl();
+
+ /**
+ * @param jdbcUrl
+ * the new jdbc url
+ */
+ @ConfigurationPropertySetter
+ @ConfigurationXPath("/configuration/services/database/jdbc/url")
+ void setJdbcUrl(String jdbcUrl);
+
+ /**
+ * @return the jdbc driver class
+ */
+ @ConfigurationPropertyGetter(defaultValue = "com.jdbc.jdbc.Driver")
+ @ConfigurationXPath("/configuration/services/database/jdbc/driver")
+ Class> getDriver();
+
+ /**
+ * @param driver
+ * the new jdbc driver
+ */
+ @ConfigurationPropertySetter
+ @ConfigurationXPath("/configuration/services/database/jdbc/driver")
+ void setDriver(Class> driver);
+
+ /**
+ * @return the sql template class
+ */
+ @ConfigurationPropertyGetter(defaultValue = "com.mysema.query.sql.MySQLTemplates")
+ @ConfigurationXPath("/configuration/services/database/jdbc/templates")
+ Class extends SQLTemplates> getSQLTemplatesClass();
+
+ /**
+ * @param templatesClass
+ * the new sql template class
+ */
+ @ConfigurationPropertySetter
+ @ConfigurationXPath("/configuration/services/database/jdbc/templates")
+ void setSQLTemplatesClass(Class extends SQLTemplates> templatesClass);
+
+ /**
+ * @return the sql template class
+ */
+ @ConfigurationPropertyGetter(defaultValue = "com.mysema.query.sql.mysql.MySQLQueryFactory")
+ @ConfigurationXPath("/configuration/services/database/jdbc/queryFactory")
+ Class extends SQLQueryFactory, ?, ?, ?, ?, ?>> getSQLQueryFactoryClass();
+
+ /**
+ * @param factoryClass
+ * the new sql query factory class
+ */
+ @ConfigurationPropertySetter
+ @ConfigurationXPath("/configuration/services/database/jdbc/queryFactory")
+ void setSQLQueryFactoryClass(
+ Class extends SQLQueryFactory, ?, ?, ?, ?, ?>> factoryClass);
+
+ /**
+ * @return the jdbc database username
+ */
+ @ConfigurationPropertyGetter(defaultValue = "l2j")
+ @ConfigurationXPath("/configuration/services/database/jdbc/username")
+ String getUsername();
+
+ /**
+ * @param username
+ * the jdbc database username
+ */
+ @ConfigurationPropertySetter
+ @ConfigurationXPath("/configuration/services/database/jdbc/username")
+ void setUsername(String username);
+
+ /**
+ * @return the jdbc database password
+ */
+ @ConfigurationPropertyGetter(defaultValue = "changeme")
+ @ConfigurationXPath("/configuration/services/database/jdbc/password")
+ String getPassword();
+
+ /**
+ * @param password
+ * the jdbc database password
+ */
+ @ConfigurationPropertySetter
+ @ConfigurationXPath("/configuration/services/database/jdbc/password")
+ void setPassword(String password);
+
+ /**
+ * @return the maximum number of active connections
+ */
+ @ConfigurationPropertyGetter(defaultValue = "20")
+ @ConfigurationXPath("/configuration/services/database/connections/active-maximum")
+ int getMaxActiveConnections();
+
+ /**
+ * @param password
+ * the maximum number of active connections
+ */
+ @ConfigurationPropertySetter
+ @ConfigurationXPath("/configuration/services/database/connections/active-maximum")
+ void setMaxActiveConnections(int password);
+
+ /**
+ * @return the maximum number of idle connections
+ */
+ @ConfigurationPropertyGetter(defaultValue = "20")
+ @ConfigurationXPath("/configuration/services/database/connections/idle-maximum")
+ int getMaxIdleConnections();
+
+ /**
+ * @param password
+ * the maximum number of idle connections
+ */
+ @ConfigurationPropertySetter
+ @ConfigurationXPath("/configuration/services/database/connections/idle-maximum")
+ void setMaxIdleConnections(int password);
+
+ /**
+ * @return the minimum number of idle connections
+ */
+ @ConfigurationPropertyGetter(defaultValue = "5")
+ @ConfigurationXPath("/configuration/services/database/connections/idle-minimum")
+ int getMinIdleConnections();
+
+ /**
+ * @param password
+ * the minimum number of idle connections
+ */
+ @ConfigurationPropertySetter
+ @ConfigurationXPath("/configuration/services/database/connections/idle-minimum")
+ void setMinIdleConnections(int password);
+ }
+
+ /**
+ * @param configService
+ * the configuration service
+ * @param cacheService
+ * the cache service
+ * @param threadService
+ * the thread service
+ * @param daoResolver
+ * the {@link DataAccessObject DAO} resolver
+ * @param types
+ * the SQL mapping types
+ */
+ @Inject
+ public AbstractJDBCDatabaseService(ConfigurationService configService,
+ CacheService cacheService, ThreadService threadService,
+ DAOResolver daoResolver, Type>... types) {
+ config = configService.get(JDBCDatabaseConfiguration.class);
+ this.cacheService = cacheService;
+ this.threadService = threadService;
+ this.daoResolver = daoResolver;
+ this.sqlTypes = types;
+ }
+
+ @Override
+ protected void doStart() throws ServiceStartException {
+ connectionPool = new GenericObjectPool(null);
+ connectionPool.setMaxActive(config.getMaxActiveConnections());
+ connectionPool.setMinIdle(config.getMinIdleConnections());
+ connectionPool.setMaxIdle(config.getMaxIdleConnections());
+
+ // test if connections are active while idle
+ connectionPool.setTestWhileIdle(true);
+
+ connectionFactory = new DriverManagerConnectionFactory(
+ config.getJdbcUrl(), config.getUsername(), config.getPassword());
+ poolableConnectionFactory = new PoolableConnectionFactory(
+ connectionFactory, connectionPool, null, "SELECT 1", false,
+ true);
+ dataSource = new PoolingDataSource(connectionPool);
+
+ try {
+ queryTemplates = config.getSQLTemplatesClass()
+ .getConstructor(Boolean.TYPE).newInstance(true);
+ } catch (InstantiationException | IllegalAccessException
+ | IllegalArgumentException | InvocationTargetException
+ | NoSuchMethodException | SecurityException e) {
+ throw new ServiceStartException(e);
+ }
+ queryConfig = new Configuration(queryTemplates);
+ for (final Type> type : sqlTypes) {
+ queryConfig.register(type);
+ }
+
+ // cache must be large enough for all world objects, to avoid
+ // duplication... this would endanger non-persistent states
+ objectCache = cacheService.createEternalCache("database-service",
+ IDAllocator.ALLOCABLE_IDS);
+
+ // start the auto save task
+ autoSaveFuture = threadService.async(60, TimeUnit.SECONDS, 60,
+ new Runnable() {
+ @Override
+ public void run() {
+ try {
+ log.debug("Auto save task started");
+ int objects = 0;
+ for (final Model> object : objectCache) {
+ @SuppressWarnings("unchecked")
+ final DataAccessObject, ?> dao = (DataAccessObject, ?>) daoResolver
+ .getDAO(object.getClass());
+ if (dao == null)
+ continue;
+ if (dao.save(object) > 0) {
+ objects++;
+ }
+ }
+ log.info(
+ "{} objects have been saved by the auto save task",
+ objects);
+ } catch (Exception e) {
+ log.error("Error occured in save thread", e);
+ }
+ }
+ });
+ }
+
+ @Override
+ public int transaction(TransactionExecutor executor) {
+ Preconditions.checkNotNull(executor, "executor");
+ try {
+ final Connection conn = dataSource.getConnection();
+ log.debug("Executing transaction {} with {}", executor, conn);
+ try {
+ conn.setAutoCommit(false);
+
+ transactionalConnection.set(conn);
+ final int rows = executor.perform();
+
+ conn.commit();
+ return rows;
+ } catch (Exception e) {
+ conn.rollback();
+ throw e;
+ } finally {
+ transactionalConnection.set(null);
+ transactionalConnection.remove();
+ conn.setAutoCommit(true);
+ conn.close();
+ }
+ } catch (DatabaseException e) {
+ throw e;
+ } catch (Throwable e) {
+ throw new DatabaseException(e);
+ }
+ }
+
+ @Override
+ public AsyncFuture transactionAsync(
+ final TransactionExecutor executor) {
+ return threadService.async(new AbstractTask() {
+ @Override
+ public Integer call() throws Exception {
+ return transaction(executor);
+ }
+ });
+ }
+
+ /**
+ * Executes an query in the database.
+ *
+ * @param
+ * the query return type
+ * @param query
+ * the query
+ * @return an instance of T
+ * @throws DatabaseException
+ * if any exception occur (can have nested {@link SQLException})
+ */
+ public T query(Query query) throws DatabaseException {
+ Preconditions.checkNotNull(query, "query");
+ try {
+ boolean inTransaction = true;
+ Connection conn = transactionalConnection.get();
+ if (conn == null) {
+ System.out.println("new connection!");
+ log.debug(
+ "Transactional connection for {} is not set, creating new connection",
+ query);
+ inTransaction = false;
+ conn = dataSource.getConnection();
+ }
+ log.debug("Executing query {} with {}", query, conn);
+ try {
+ if (!inTransaction) {
+ conn.setAutoCommit(false);
+ }
+ try {
+ final Connection retConn = conn;
+ final SQLQueryFactory extends AbstractSQLQuery>, ?, ?, ?, ?, ?> factory = createQueryFactory(new Provider() {
+ @Override
+ public Connection get() {
+ return retConn;
+ }
+ });
+ return query.query(factory);
+ } finally {
+ if (!inTransaction) {
+ conn.commit();
+ }
+ }
+ } catch (Exception e) {
+ if (!inTransaction) {
+ conn.rollback();
+ }
+ throw e;
+ } finally {
+ if (!inTransaction) {
+ conn.setAutoCommit(true);
+ conn.close();
+ }
+ }
+ } catch (Throwable e) {
+ log.error("Could not open database connection", e);
+ throw new DatabaseException(e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private SQLQueryFactory extends AbstractSQLQuery>, ?, ?, ?, ?, ?> createQueryFactory(
+ Provider provider) {
+ try {
+ return (SQLQueryFactory extends AbstractSQLQuery>, ?, ?, ?, ?, ?>) config
+ .getSQLQueryFactoryClass()
+ .getConstructor(Configuration.class, Provider.class)
+ .newInstance(queryConfig, provider);
+ } catch (InstantiationException | IllegalAccessException
+ | IllegalArgumentException | InvocationTargetException
+ | NoSuchMethodException | SecurityException e) {
+ return null;
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public , O extends Model>> O getCachedObject(I id) {
+ Preconditions.checkNotNull(id, "id");
+ log.debug("Fetching cached object {}", id);
+ return (O) objectCache.get(id);
+ }
+
+ @Override
+ public , O extends Model>> boolean hasCachedObject(I id) {
+ Preconditions.checkNotNull(id, "id");
+ log.debug("Locating cached object {}", id);
+ return objectCache.contains(id);
+ }
+
+ @Override
+ public , O extends Model>> void updateCache(I id, O value) {
+ Preconditions.checkNotNull(id, "key");
+ Preconditions.checkNotNull(value, "value");
+ log.debug("Updating cached object {} with {}", id, value);
+ objectCache.put(id, value);
+ }
+
+ @Override
+ public , O extends Model>> void removeCache(I id) {
+ Preconditions.checkNotNull(id, "key");
+ log.debug("Removing cached object {}", id);
+ objectCache.remove(id);
+ }
+
+ @Override
+ protected void doStop() throws ServiceStopException {
+ autoSaveFuture.cancel(true);
+ autoSaveFuture = null;
+ cacheService.dispose(objectCache);
+ objectCache = null;
+
+ try {
+ if (connectionPool != null)
+ connectionPool.close();
+ } catch (Exception e) {
+ log.error("Error stopping database service", e);
+ throw new ServiceStopException(e);
+ } finally {
+ connectionPool = null;
+ connectionFactory = null;
+ poolableConnectionFactory = null;
+ dataSource = null;
+ }
+ }
+
+ /**
+ * The query interface. The query will receive an connection an will be
+ * executed. The can return return a value if required.
+ *
+ * @author Rogiel
+ *
+ * @param
+ * the return type
+ */
+ public interface Query {
+ /**
+ * Execute the query in conn
+ *
+ * @param factory
+ * the query factory (database specific)
+ * @return the query return value
+ */
+ R query(SQLQueryFactory extends AbstractSQLQuery>, ?, ?, ?, ?, ?> factory);
+ }
+
+ public static abstract class AbstractQuery implements Query {
+ protected void updateDesire(Object object, ObjectDesire expected) {
+ if (object instanceof Model) {
+ if (((Model>) object).getObjectDesire() == expected) {
+ ((Model>) object).setObjectDesire(ObjectDesire.NONE);
+ }
+ }
+ }
+ }
+
+ public static abstract class InsertQuery, K>
+ extends AbstractQuery {
+ private final Iterator iterator;
+ private final Path primaryKey;
+
+ protected final E e;
+
+ /**
+ * @param entity
+ * the entity type
+ * @param iterator
+ * the objects to be inserted
+ * @param primaryKey
+ * the primary key, if any. Only required if the ID is
+ * generated by the database engine.
+ */
+ public InsertQuery(E entity, Path primaryKey, Iterator iterator) {
+ this.iterator = iterator;
+ this.e = entity;
+ this.primaryKey = primaryKey;
+ }
+
+ /**
+ * @param entity
+ * the entity type
+ * @param iterator
+ * the objects to be inserted
+ */
+ public InsertQuery(E entity, Iterator iterator) {
+ this(entity, null, iterator);
+ }
+
+ /**
+ * @param entity
+ * the entity type
+ * @param objects
+ * the objects to be inserted
+ */
+ @SafeVarargs
+ public InsertQuery(E entity, O... objects) {
+ this(entity, null, Iterators.forArray(objects));
+ }
+
+ /**
+ * @param entity
+ * the entity type
+ * @param objects
+ * the objects to be inserted
+ * @param primaryKey
+ * the primary key, if any. Only required if the ID is
+ * generated by the database engine.
+ */
+ @SafeVarargs
+ public InsertQuery(E entity, Path primaryKey, O... objects) {
+ this(entity, primaryKey, Iterators.forArray(objects));
+ }
+
+ @Override
+ public final Integer query(
+ SQLQueryFactory extends AbstractSQLQuery>, ?, ?, ?, ?, ?> factory) {
+ int rows = 0;
+ while (iterator.hasNext()) {
+ final O object = iterator.next();
+ final SQLInsertClause insert = factory.insert(e);
+ // maps query to the values
+ map(insert, object);
+
+ if (primaryKey == null) {
+ insert.execute();
+ } else {
+ final K key = insert.executeWithKey(primaryKey);
+ key(key, object);
+ }
+ rows++;
+
+ updateDesire(object, ObjectDesire.INSERT);
+ }
+ return rows;
+ }
+
+ protected abstract void map(SQLInsertClause q, O o);
+
+ protected void key(K k, O o) {
+ }
+ }
+
+ public static abstract class UpdateQuery>
+ extends AbstractQuery {
+ private final Iterator iterator;
+ protected final E e;
+
+ /**
+ * @param entity
+ * the entity type
+ * @param iterator
+ * the objects to be inserted
+ */
+ public UpdateQuery(E entity, Iterator iterator) {
+ this.iterator = iterator;
+ this.e = entity;
+ }
+
+ /**
+ * @param entity
+ * the entity type
+ * @param objects
+ * the objects to be inserted
+ */
+ @SafeVarargs
+ public UpdateQuery(E entity, O... objects) {
+ this(entity, Iterators.forArray(objects));
+ }
+
+ @Override
+ public final Integer query(
+ SQLQueryFactory extends AbstractSQLQuery>, ?, ?, ?, ?, ?> factory) {
+ int rows = 0;
+ while (iterator.hasNext()) {
+ final O object = iterator.next();
+ final SQLUpdateClause update = factory.update(e);
+ // maps query to the values
+ query(update, object);
+ map(update, object);
+
+ rows += update.execute();
+
+ updateDesire(object, ObjectDesire.UPDATE);
+ }
+ return rows;
+ }
+
+ protected abstract void query(SQLUpdateClause q, O o);
+
+ protected abstract void map(SQLUpdateClause q, O o);
+ }
+
+ public static abstract class DeleteQuery>
+ extends AbstractQuery {
+ private final Iterator iterator;
+ protected final E e;
+
+ /**
+ * @param entity
+ * the entity type
+ * @param iterator
+ * the objects to be inserted
+ */
+ public DeleteQuery(E entity, Iterator iterator) {
+ this.iterator = iterator;
+ this.e = entity;
+ }
+
+ /**
+ * @param entity
+ * the entity type
+ * @param objects
+ * the objects to be inserted
+ */
+ @SafeVarargs
+ public DeleteQuery(E entity, O... objects) {
+ this(entity, Iterators.forArray(objects));
+ }
+
+ @Override
+ public final Integer query(
+ SQLQueryFactory extends AbstractSQLQuery>, ?, ?, ?, ?, ?> factory) {
+ int rows = 0;
+ while (iterator.hasNext()) {
+ final O object = iterator.next();
+ final SQLDeleteClause delete = factory.delete(e);
+ // maps query to the values
+ query(delete, object);
+
+ rows += delete.execute();
+
+ updateDesire(object, ObjectDesire.DELETE);
+ }
+ return rows;
+ }
+
+ protected abstract void query(SQLDeleteClause q, O o);
+ }
+
+ public static abstract class AbstractSelectQuery>
+ extends AbstractQuery {
+ protected final E entity;
+ protected final Mapper mapper;
+
+ /**
+ * @param entity
+ * the entity type
+ * @param mapper
+ * the object mapper
+ */
+ public AbstractSelectQuery(E entity, Mapper mapper) {
+ this.entity = entity;
+ this.mapper = mapper;
+ }
+
+ @Override
+ public final R query(
+ SQLQueryFactory extends AbstractSQLQuery>, ?, ?, ?, ?, ?> factory) {
+ final AbstractSQLQuery> select = factory.query();
+ // maps query to the values
+ select.from(entity);
+ query(select, entity);
+ return perform(select);
+ }
+
+ protected abstract void query(AbstractSQLQuery> q, E e);
+
+ protected abstract R perform(AbstractSQLQuery> select);
+ }
+
+ public static abstract class SelectSingleQuery>
+ extends AbstractSelectQuery {
+ /**
+ * @param entity
+ * the entity
+ * @param mapper
+ * the mapper
+ */
+ public SelectSingleQuery(E entity, Mapper mapper) {
+ super(entity, mapper);
+ }
+
+ @Override
+ protected final O perform(AbstractSQLQuery> select) {
+ final List results = select.limit(1).list(entity.all());
+ if (results.size() == 1) {
+ return mapper.map(entity, new JDBCDatabaseRow(results.get(0),
+ entity));
+ } else {
+ return null;
+ }
+ }
+ }
+
+ public static abstract class SelectListQuery>
+ extends AbstractSelectQuery, O, E> {
+ /**
+ * @param entity
+ * the entity
+ * @param mapper
+ * the mapper
+ */
+ public SelectListQuery(E entity, Mapper mapper) {
+ super(entity, mapper);
+ }
+
+ @Override
+ protected final List perform(AbstractSQLQuery> select) {
+ final List results = select.list(entity.all());
+ final JDBCDatabaseRow row = new JDBCDatabaseRow(entity);
+ final List objects = CollectionFactory.newList();
+ for (final Object[] data : results) {
+ row.setRow(data);
+ final O object = mapper.map(entity, row);
+ if (object != null)
+ objects.add(object);
+ }
+ return objects;
+ }
+ }
+}
diff --git a/l2jserver2-common/src/main/java/com/l2jserver/service/database/jdbc/JDBCDatabaseRow.java b/l2jserver2-common/src/main/java/com/l2jserver/service/database/jdbc/JDBCDatabaseRow.java
new file mode 100644
index 000000000..06c63183d
--- /dev/null
+++ b/l2jserver2-common/src/main/java/com/l2jserver/service/database/jdbc/JDBCDatabaseRow.java
@@ -0,0 +1,76 @@
+/*
+ * 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.service.database.jdbc;
+
+import java.util.List;
+
+import com.l2jserver.service.database.dao.DatabaseRow;
+import com.mysema.query.sql.RelationalPathBase;
+import com.mysema.query.types.Path;
+
+/**
+ * @author Rogiel
+ *
+ */
+public class JDBCDatabaseRow implements DatabaseRow {
+ @SuppressWarnings("unused")
+ private final RelationalPathBase> entity;
+ private final List> paths;
+
+ private Object[] row;
+
+ /**
+ * @param row
+ * the database row data
+ * @param entity
+ * the entity
+ */
+ public JDBCDatabaseRow(Object[] row, RelationalPathBase> entity) {
+ this.row = row;
+ this.entity = entity;
+ paths = entity.getColumns();
+ }
+
+ /**
+ * @param entity
+ * the entity
+ */
+ public JDBCDatabaseRow(RelationalPathBase> entity) {
+ this.entity = entity;
+ paths = entity.getColumns();
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public T get(Path path) {
+ // this cast should be safe!
+ return (T) row[indexOf(path)];
+ }
+
+ @Override
+ public boolean isNull(Path path) {
+ return row[indexOf(path)] == null;
+ }
+
+ private int indexOf(Path> path) {
+ return paths.indexOf(path);
+ }
+
+ public void setRow(Object[] row) {
+ this.row = row;
+ }
+}
diff --git a/l2jserver2-common/src/main/java/com/l2jserver/util/geometry/Coordinate.java b/l2jserver2-common/src/main/java/com/l2jserver/util/geometry/Coordinate.java
index 1c14a25cd..3585dfa50 100644
--- a/l2jserver2-common/src/main/java/com/l2jserver/util/geometry/Coordinate.java
+++ b/l2jserver2-common/src/main/java/com/l2jserver/util/geometry/Coordinate.java
@@ -18,10 +18,11 @@ package com.l2jserver.util.geometry;
import org.apache.commons.math.geometry.Vector3D;
+
/**
* Represents an coordinate in the game world.
*
- * Each coordinate has 3 points: x, y and z.
+ * Each coordinate has 3 axis: x, y and z.
*
* @author Rogiel
*/
diff --git a/l2jserver2-gameserver/config/config.xml b/l2jserver2-gameserver/config/config.xml
index 0324e7261..cfdcc2278 100644
--- a/l2jserver2-gameserver/config/config.xml
+++ b/l2jserver2-gameserver/config/config.xml
@@ -27,6 +27,16 @@
driver library must be available in the JVM classpath. -->
com.mysql.jdbc.Driver
+
+ com.mysema.query.sql.MySQLTemplates
+
+
+ com.mysema.query.sql.mysql.MySQLQueryFactory
+
+
l2j
diff --git a/l2jserver2-gameserver/distribution/global/config/config.xml b/l2jserver2-gameserver/distribution/global/config/config.xml
index 0324e7261..1749dbaf7 100644
--- a/l2jserver2-gameserver/distribution/global/config/config.xml
+++ b/l2jserver2-gameserver/distribution/global/config/config.xml
@@ -26,6 +26,16 @@
com.mysql.jdbc.Driver
+
+
+ com.mysema.query.sql.MySQLTemplates
+
+
+ com.mysema.query.sql.mysql.MySQLQueryFactory
+
diff --git a/l2jserver2-gameserver/pom.xml b/l2jserver2-gameserver/pom.xml
index cdf49f95f..366204fa0 100644
--- a/l2jserver2-gameserver/pom.xml
+++ b/l2jserver2-gameserver/pom.xml
@@ -21,7 +21,6 @@
src/main/assembly/distribution-mysql5-bin.xml
src/main/assembly/distribution-h2-bin.xml
- src/main/assembly/distribution-orientdb-bin.xml
src/main/assembly/distribution-derby-bin.xml
src/main/assembly/distribution-src.xml
@@ -83,12 +82,6 @@
10.8.2.2
runtime
-
- com.orientechnologies
- orientdb-core
- 1.0rc7
- jar
-
net.sf.ehcache
diff --git a/l2jserver2-gameserver/src/main/assembly/distribution-derby-bin.xml b/l2jserver2-gameserver/src/main/assembly/distribution-derby-bin.xml
index 7d172c808..700c83281 100644
--- a/l2jserver2-gameserver/src/main/assembly/distribution-derby-bin.xml
+++ b/l2jserver2-gameserver/src/main/assembly/distribution-derby-bin.xml
@@ -48,7 +48,6 @@
mysql:*
com.h2database:*
- com.orientechnologies:*
diff --git a/l2jserver2-gameserver/src/main/assembly/distribution-h2-bin.xml b/l2jserver2-gameserver/src/main/assembly/distribution-h2-bin.xml
index b55dd905e..8602e3f79 100644
--- a/l2jserver2-gameserver/src/main/assembly/distribution-h2-bin.xml
+++ b/l2jserver2-gameserver/src/main/assembly/distribution-h2-bin.xml
@@ -48,7 +48,6 @@
mysql:*
org.apache.derby:*
- com.orientechnologies:*
diff --git a/l2jserver2-gameserver/src/main/assembly/distribution-mysql5-bin.xml b/l2jserver2-gameserver/src/main/assembly/distribution-mysql5-bin.xml
index 00ed73d3a..35b726b6c 100644
--- a/l2jserver2-gameserver/src/main/assembly/distribution-mysql5-bin.xml
+++ b/l2jserver2-gameserver/src/main/assembly/distribution-mysql5-bin.xml
@@ -47,7 +47,6 @@
com.h2database:*
org.apache.derby:*
- com.orientechnologies:*
diff --git a/l2jserver2-gameserver/src/main/assembly/distribution-orientdb-bin.xml b/l2jserver2-gameserver/src/main/assembly/distribution-orientdb-bin.xml
deleted file mode 100644
index b6da2c8fc..000000000
--- a/l2jserver2-gameserver/src/main/assembly/distribution-orientdb-bin.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-
- orientdb-bin
-
- zip
-
-
-
-
- ${project.basedir}
- /
-
- data/**
-
-
- .gitignore
- data/cache/**
- data/pathing.db
- data/database/derby/**
- data/database/h2/**
-
-
-
- ${project.basedir}/distribution/global
- /
-
-
- ${project.basedir}/distribution/sql
- /
-
-
-
-
- ${project.build.directory}/${project.artifactId}-${project.version}.jar
- /
- l2jserver2.jar
- 0755
-
-
-
-
- /libs
- true
- false
- runtime
-
- mysql:*
- com.h2database:*
- org.apache.derby:*
-
-
-
-
\ No newline at end of file
diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerJDBCDatabaseService.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerJDBCDatabaseService.java
index 6f14a2dc6..3531bcdd9 100644
--- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerJDBCDatabaseService.java
+++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerJDBCDatabaseService.java
@@ -16,50 +16,48 @@
*/
package com.l2jserver.service.database;
-import java.sql.ResultSet;
-
import com.google.inject.Inject;
-import com.l2jserver.model.Model;
-import com.l2jserver.model.id.ID;
+import com.l2jserver.model.game.CharacterShortcut.ShortcutType;
+import com.l2jserver.model.template.actor.ActorSex;
+import com.l2jserver.model.template.character.CharacterClass;
+import com.l2jserver.model.template.character.CharacterRace;
+import com.l2jserver.model.world.character.CharacterAppearance.CharacterFace;
+import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairColor;
+import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairStyle;
+import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
+import com.l2jserver.model.world.character.CharacterInventory.ItemLocation;
import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.cache.CacheService;
import com.l2jserver.service.configuration.ConfigurationService;
import com.l2jserver.service.core.LoggingService;
import com.l2jserver.service.core.threading.ThreadService;
+import com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService;
+import com.l2jserver.service.game.chat.ChatMessageType;
import com.l2jserver.service.game.template.TemplateService;
+import com.mysema.query.sql.types.EnumByNameType;
/**
* This is an implementation of {@link DatabaseService} that provides an layer
* to JDBC.
*
* Internal specification The
- * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Query
+ * {@link com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.Query
* Query} object
*
* If you wish to implement a new {@link DataAccessObject} you should try not
- * use {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Query
+ * use
+ * {@link com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.Query
* Query} object directly because it only provides low level access to the JDBC
* architecture. Instead, you could use an specialized class, like
- * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.InsertUpdateQuery
+ * {@link com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.InsertQuery
* InsertUpdateQuery} ,
- * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.SelectListQuery
+ * {@link com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.SelectListQuery
* SelectListQuery} or
- * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.SelectSingleQuery
+ * {@link com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.SelectSingleQuery
* SelectSingleQuery} . If you do need low level access, feel free to use the
- * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Query
+ * {@link com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.Query
* Query} class directly.
*
- * The
- * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Mapper
- * Mapper} object
- *
- * The {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Mapper
- * Mapper} object maps an JDBC {@link ResultSet} into an Java {@link Object}.
- * All {@link Model} objects support
- * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.CachedMapper
- * CachedMapper} that will cache result based on its {@link ID} and always use
- * the same object with the same {@link ID}.
- *
* @author Rogiel
*/
@Depends({ LoggingService.class, CacheService.class,
@@ -80,6 +78,20 @@ public class GameServerJDBCDatabaseService extends AbstractJDBCDatabaseService
public GameServerJDBCDatabaseService(ConfigurationService configService,
CacheService cacheService, ThreadService threadService,
DAOResolver daoResolver) {
- super(configService, cacheService, threadService, daoResolver);
+ super(
+ configService,
+ cacheService,
+ threadService,
+ daoResolver,
+ new EnumByNameType(CharacterRace.class),
+ new EnumByNameType(CharacterClass.class),
+ new EnumByNameType(ActorSex.class),
+ new EnumByNameType(CharacterHairColor.class),
+ new EnumByNameType(CharacterHairStyle.class),
+ new EnumByNameType(CharacterFace.class),
+ new EnumByNameType(ShortcutType.class),
+ new EnumByNameType(ItemLocation.class),
+ new EnumByNameType(InventoryPaperdoll.class),
+ new EnumByNameType(ChatMessageType.class));
}
}
diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerOrientDatabaseService.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerOrientDatabaseService.java
deleted file mode 100644
index a93ea347b..000000000
--- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/GameServerOrientDatabaseService.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.service.database;
-
-import java.sql.ResultSet;
-
-import com.google.inject.Inject;
-import com.l2jserver.model.Model;
-import com.l2jserver.model.id.ID;
-import com.l2jserver.service.AbstractService.Depends;
-import com.l2jserver.service.cache.CacheService;
-import com.l2jserver.service.configuration.ConfigurationService;
-import com.l2jserver.service.core.LoggingService;
-import com.l2jserver.service.core.threading.ThreadService;
-import com.l2jserver.service.game.template.TemplateService;
-
-/**
- * This is an implementation of {@link DatabaseService} that provides an layer
- * to JDBC.
- *
- * Internal specification The
- * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Query
- * Query} object
- *
- * If you wish to implement a new {@link DataAccessObject} you should try not
- * use {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Query
- * Query} object directly because it only provides low level access to the JDBC
- * architecture. Instead, you could use an specialized class, like
- * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.InsertUpdateQuery
- * InsertUpdateQuery} ,
- * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.SelectListQuery
- * SelectListQuery} or
- * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.SelectSingleQuery
- * SelectSingleQuery} . If you do need low level access, feel free to use the
- * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Query
- * Query} class directly.
- *
- * The
- * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Mapper
- * Mapper} object
- *
- * The {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Mapper
- * Mapper} object maps an JDBC {@link ResultSet} into an Java {@link Object}.
- * All {@link Model} objects support
- * {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.CachedMapper
- * CachedMapper} that will cache result based on its {@link ID} and always use
- * the same object with the same {@link ID}.
- *
- * @author Rogiel
- */
-@Depends({ LoggingService.class, CacheService.class,
- ConfigurationService.class, TemplateService.class, ThreadService.class })
-public class GameServerOrientDatabaseService extends
- AbstractOrientDatabaseService implements DatabaseService {
- /**
- * @param configService
- * the config service
- * @param cacheService
- * the cache service
- * @param threadService
- * the thread service
- * @param daoResolver
- * the {@link DataAccessObject DAO} resolver
- */
- @Inject
- public GameServerOrientDatabaseService(ConfigurationService configService,
- CacheService cacheService, ThreadService threadService,
- DAOResolver daoResolver) {
- super(configService, cacheService, threadService, daoResolver);
- }
-}
diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/OrientDBDAOModule.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/OrientDBDAOModule.java
deleted file mode 100644
index d79b38f1d..000000000
--- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/OrientDBDAOModule.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.service.database;
-
-import com.google.inject.AbstractModule;
-import com.google.inject.Module;
-import com.google.inject.Scopes;
-import com.l2jserver.model.dao.CharacterDAO;
-import com.l2jserver.service.database.orientdb.OrientDBCharacterDAO;
-
-/**
- * Google Guice {@link Module} for Orient Database DAOs
- *
- * @author Rogiel
- */
-public class OrientDBDAOModule extends AbstractModule {
- @Override
- protected void configure() {
- bind(CharacterDAO.class).to(OrientDBCharacterDAO.class).in(
- Scopes.SINGLETON);
- // bind(CharacterFriendDAO.class).to(OrientDBCharacterFriendDAO.class).in(
- // Scopes.SINGLETON);
- //
- // bind(NPCDAO.class).to(OrientDBNPCDAO.class).in(Scopes.SINGLETON);
- //
- // bind(ItemDAO.class).to(OrientDBItemDAO.class).in(Scopes.SINGLETON);
- // bind(ClanDAO.class).to(OrientDBClanDAO.class).in(Scopes.SINGLETON);
- //
- // // logs
- // bind(ChatMessageDAO.class).to(OrientDBChatMessageDAO.class).in(
- // Scopes.SINGLETON);
-
- // DAO Resolver
- bind(DAOResolver.class).to(GameServerDAOResolver.class).in(
- Scopes.SINGLETON);
- }
-}
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 0b5749135..3d5a3089d 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
@@ -16,10 +16,6 @@
*/
package com.l2jserver.service.database.jdbc;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
import java.util.List;
import com.google.inject.Inject;
@@ -27,407 +23,178 @@ import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterDAO;
import com.l2jserver.model.id.AccountID;
import com.l2jserver.model.id.object.CharacterID;
-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.id.provider.AccountIDProvider;
-import com.l2jserver.model.id.template.CharacterTemplateID;
-import com.l2jserver.model.id.template.provider.CharacterTemplateIDProvider;
-import com.l2jserver.model.template.actor.ActorSex;
-import com.l2jserver.model.template.character.CharacterClass;
-import com.l2jserver.model.template.character.CharacterRace;
-import com.l2jserver.model.template.character.CharacterTemplate;
import com.l2jserver.model.world.Clan;
import com.l2jserver.model.world.L2Character;
-import com.l2jserver.model.world.character.CharacterAppearance;
-import com.l2jserver.model.world.character.CharacterAppearance.CharacterFace;
-import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairColor;
-import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairStyle;
-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;
-import com.l2jserver.util.geometry.Point3D;
+import com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.DeleteQuery;
+import com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.InsertQuery;
+import com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.SelectListQuery;
+import com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.SelectSingleQuery;
+import com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.UpdateQuery;
+import com.l2jserver.service.database.mapper.CharacterMapper;
+import com.l2jserver.service.database.model.QCharacter;
+import com.mysema.query.sql.AbstractSQLQuery;
+import com.mysema.query.sql.dml.SQLDeleteClause;
+import com.mysema.query.sql.dml.SQLInsertClause;
+import com.mysema.query.sql.dml.SQLUpdateClause;
/**
* {@link CharacterDAO} implementation for JDBC
*
* @author Rogiel
*/
-public class JDBCCharacterDAO extends
- AbstractJDBCDAO implements CharacterDAO {
+public class JDBCCharacterDAO extends AbstractJDBCDAO
+ implements CharacterDAO {
/**
- * The {@link CharacterID} factory
+ * The {@link L2Character} mapper
*/
- private final CharacterIDProvider idFactory;
- /**
- * The {@link CharacterTemplateID} factory
- */
- private final CharacterTemplateIDProvider templateIdFactory;
- /**
- * The {@link AccountID} factory
- */
- private final AccountIDProvider accountIdFactory;
- /**
- * The {@link ClanID} factory
- */
- private final ClanIDProvider clanIdFactory;
-
- /**
- * Character table name
- */
- public static final String TABLE = "character";
- // FIELDS
- public static final String CHAR_ID = "character_id";
- public static final String ACCOUNT_ID = "account_id";
- public static final String CLAN_ID = "clan_id";
- public static final String NAME = "name";
-
- public static final String RACE = "race";
- public static final String CLASS = "class";
- public static final String SEX = "sex";
-
- public static final String LEVEL = "level";
- public static final String EXPERIENCE = "experience";
- public static final String SP = "sp";
-
- public static final String HP = "hp";
- public static final String MP = "mp";
- public static final String CP = "cp";
-
- public static final String POINT_X = "point_x";
- public static final String POINT_Y = "point_y";
- public static final String POINT_Z = "point_z";
- public static final String POINT_ANGLE = "point_angle";
-
- public static final String APPEARANCE_HAIR_STYLE = "appearance_hair_style";
- public static final String APPEARANCE_HAIR_COLOR = "appearance_hair_color";
- public static final String APPEARANCE_FACE = "apperance_face";
+ private final CharacterMapper mapper;
/**
* @param database
* the database service
- * @param idFactory
- * the character id provider
- * @param templateIdFactory
- * the template id provider
- * @param accountIdFactory
- * the account id provider
- * @param clanIdFactory
- * the clan id provider
+ * @param mapper
+ * the character mapper
*/
@Inject
- public JDBCCharacterDAO(DatabaseService database,
- final CharacterIDProvider idFactory,
- CharacterTemplateIDProvider templateIdFactory,
- AccountIDProvider accountIdFactory, ClanIDProvider clanIdFactory) {
+ public JDBCCharacterDAO(DatabaseService database, CharacterMapper mapper) {
super(database);
- this.idFactory = idFactory;
- this.templateIdFactory = templateIdFactory;
- this.accountIdFactory = accountIdFactory;
- this.clanIdFactory = clanIdFactory;
+ this.mapper = mapper;
}
- /**
- * The mapper for {@link CharacterID}
- */
- private final Mapper idMapper = new Mapper() {
- @Override
- public CharacterID map(ResultSet rs) throws SQLException {
- return idFactory.resolveID(rs.getInt(CHAR_ID));
- }
- };
-
- /**
- * The {@link Mapper} for {@link L2Character}
- */
- private final Mapper mapper = new CachedMapper(
- database, idMapper) {
- @Override
- protected L2Character map(CharacterID id, ResultSet rs)
- throws SQLException {
- final CharacterClass charClass = CharacterClass.valueOf(rs
- .getString(CLASS));
- final CharacterTemplateID templateId = templateIdFactory
- .resolveID(charClass.id);
- final CharacterTemplate template = templateId.getTemplate();
-
- final L2Character character = template.create();
-
- character.setID(id);
- character.setAccountID(accountIdFactory.resolveID(rs
- .getString(ACCOUNT_ID)));
- if (rs.getString(CLAN_ID) != null)
- character
- .setClanID(clanIdFactory.resolveID(rs.getInt(CLAN_ID)));
-
- character.setName(rs.getString(NAME));
-
- character.setRace(CharacterRace.valueOf(rs.getString(RACE)));
- character.setCharacterClass(CharacterClass.valueOf(rs
- .getString(CLASS)));
- character.setSex(ActorSex.valueOf(rs.getString(SEX)));
-
- character.setLevel(rs.getInt(LEVEL));
- character.setExperience(rs.getLong(EXPERIENCE));
- character.setSP(rs.getInt(SP));
-
- character.setHP(rs.getDouble(HP));
- character.setMP(rs.getDouble(MP));
- character.setCP(rs.getDouble(CP));
-
- character.setPoint(Point3D.fromXYZA(rs.getInt(POINT_X),
- rs.getInt(POINT_Y), rs.getInt(POINT_Z),
- rs.getDouble(POINT_ANGLE)));
-
- // appearance
- character.getAppearance().setHairStyle(
- CharacterHairStyle.valueOf(rs
- .getString(APPEARANCE_HAIR_STYLE)));
- character.getAppearance().setHairColor(
- CharacterHairColor.valueOf(rs
- .getString(APPEARANCE_HAIR_COLOR)));
- character.getAppearance().setFace(
- CharacterFace.valueOf(rs.getString(APPEARANCE_FACE)));
-
- return character;
- }
- };
-
@Override
public L2Character select(final CharacterID id) {
- return database.query(new SelectSingleQuery() {
+ return database.query(new SelectSingleQuery(
+ QCharacter.character, mapper) {
@Override
- protected String query() {
- return "SELECT * FROM `" + TABLE + "` WHERE `" + CHAR_ID
- + "` = ?";
- }
-
- @Override
- protected void parametize(PreparedStatement st) throws SQLException {
- st.setInt(1, id.getID());
- }
-
- @Override
- protected Mapper mapper() {
- return mapper;
+ protected void query(AbstractSQLQuery> q, QCharacter e) {
+ q.where(e.characterId.eq(id.getID()));
}
});
}
@Override
public void load(final Clan clan) {
- clan.getMembers().load(
- database.query(new SelectListQuery() {
- @Override
- protected String query() {
- return "SELECT `" + CHAR_ID + "` FROM `" + TABLE
- + "` WHERE `" + CLAN_ID + "` = ?";
- }
-
- @Override
- protected void parametize(PreparedStatement st)
- throws SQLException {
- st.setInt(1, clan.getID().getID());
- }
-
- @Override
- protected Mapper mapper() {
- return idMapper;
- }
- }));
+ clan.getMembers().load(database.query(new SelectListQuery(
+ QCharacter.character, mapper.getIDMapper()) {
+ @Override
+ protected void query(AbstractSQLQuery> q, QCharacter e) {
+ q.where(e.clanId.eq(clan.getID().getID()));
+ }
+ }));
}
@Override
public L2Character selectByName(final String name) {
- return database.query(new SelectSingleQuery() {
+ return database.query(new SelectSingleQuery(
+ QCharacter.character, mapper) {
@Override
- protected String query() {
- return "SELECT * FROM `" + TABLE + "` WHERE `" + NAME + "` = ?";
- }
-
- @Override
- protected void parametize(PreparedStatement st) throws SQLException {
- st.setString(1, name);
- }
-
- @Override
- protected Mapper mapper() {
- return mapper;
+ protected void query(AbstractSQLQuery> q, QCharacter e) {
+ q.where(e.name.eq(name));
}
});
}
@Override
public List selectByAccount(final AccountID account) {
- return database.query(new SelectListQuery() {
+ return database.query(new SelectListQuery(
+ QCharacter.character, mapper) {
@Override
- protected String query() {
- return "SELECT * FROM `" + TABLE + "` WHERE `" + ACCOUNT_ID
- + "` = ?";
- }
-
- @Override
- protected void parametize(PreparedStatement st) throws SQLException {
- st.setString(1, account.getID());
- }
-
- @Override
- protected Mapper mapper() {
- return mapper;
+ protected void query(AbstractSQLQuery> q, QCharacter e) {
+ q.where(e.accountId.eq(account.getID()));
}
});
}
@Override
public List selectIDs() {
- return database.query(new SelectListQuery() {
+ return database.query(new SelectListQuery(
+ QCharacter.character, mapper.getIDMapper()) {
@Override
- protected String query() {
- return "SELECT `" + CHAR_ID + "` FROM `" + TABLE + "`";
- }
-
- @Override
- protected Mapper mapper() {
- return idMapper;
+ protected void query(AbstractSQLQuery> q, QCharacter e) {
}
});
}
@Override
public int insertObjects(L2Character... characters) {
- return database.query(new InsertUpdateQuery(characters) {
+ return database.query(new InsertQuery(
+ QCharacter.character, characters) {
@Override
- protected String query() {
- return "INSERT INTO `" + TABLE + "` (`" + CHAR_ID + "`,`"
- + ACCOUNT_ID + "`,`" + CLAN_ID + "`,`" + NAME + "`,`"
- + RACE + "`,`" + CLASS + "`,`" + SEX + "`,`" + LEVEL
- + "`,`" + EXPERIENCE + "`,`" + SP + "`,`" + HP + "`,`"
- + MP + "`,`" + CP + "`,`" + POINT_X + "`,`" + POINT_Y
- + "`,`" + POINT_Z + "`,`" + POINT_ANGLE + "`,`"
- + APPEARANCE_HAIR_STYLE + "`,`" + APPEARANCE_HAIR_COLOR
- + "`,`" + APPEARANCE_FACE
- + "`) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
- }
-
- @Override
- protected void parametize(PreparedStatement st,
- L2Character character) throws SQLException {
- final CharacterAppearance appearance = character
- .getAppearance();
- int i = 1;
-
- st.setInt(i++, character.getID().getID());
- st.setString(i++, character.getAccountID().getID());
- if (character.getClanID() != null)
- st.setInt(i++, character.getClanID().getID());
- else
- st.setNull(i++, Types.INTEGER);
-
- st.setString(i++, character.getName());
-
- st.setString(i++, character.getRace().name());
- st.setString(i++, character.getCharacterClass().name());
- st.setString(i++, character.getSex().name());
-
- st.setInt(i++, character.getLevel());
- st.setLong(i++, character.getExperience());
- st.setInt(i++, character.getSP());
-
- st.setDouble(i++, character.getHP());
- st.setDouble(i++, character.getMP());
- st.setDouble(i++, character.getCP());
-
- st.setInt(i++, character.getPoint().getX());
- st.setInt(i++, character.getPoint().getY());
- st.setInt(i++, character.getPoint().getZ());
- st.setDouble(i++, character.getPoint().getAngle());
-
- // appearance
- st.setString(i++, appearance.getHairStyle().name());
- st.setString(i++, appearance.getHairColor().name());
- st.setString(i++, appearance.getFace().name());
+ protected void map(SQLInsertClause q, L2Character o) {
+ q.set(e.characterId, o.getID().getID())
+ .set(e.accountId, o.getAccountID().getID())
+ .set(e.clanId,
+ (o.getClanID() != null ? o.getClanID().getID()
+ : null))
+ .set(e.name, o.getName())
+ .set(e.race, o.getRace())
+ .set(e.characterClass, o.getCharacterClass())
+ .set(e.sex, o.getSex())
+ .set(e.level, o.getLevel())
+ .set(e.experience, o.getExperience())
+ .set(e.sp, o.getSP())
+ .set(e.hp, o.getHP())
+ .set(e.mp, o.getMP())
+ .set(e.cp, o.getCP())
+ .set(e.pointX, o.getPoint().getX())
+ .set(e.pointY, o.getPoint().getY())
+ .set(e.pointZ, o.getPoint().getZ())
+ .set(e.pointAngle, o.getPoint().getAngle())
+ .set(e.appearanceHairStyle,
+ o.getAppearance().getHairStyle())
+ .set(e.appearanceHairColor,
+ o.getAppearance().getHairColor())
+ .set(e.apperanceFace, o.getAppearance().getFace());
}
});
}
@Override
public int updateObjects(L2Character... characters) {
- return database.query(new InsertUpdateQuery(characters) {
+ return database.query(new UpdateQuery(
+ QCharacter.character, characters) {
@Override
- protected String query() {
- return "UPDATE `" + TABLE + "` SET `" + ACCOUNT_ID + "` = ?,`"
- + CLAN_ID + "` = ?,`" + NAME + "` = ?,`" + RACE
- + "` = ?,`" + CLASS + "` = ?,`" + SEX + "` = ?,`"
- + LEVEL + "` = ?,`" + EXPERIENCE + "` = ?,`" + SP
- + "` = ?,`" + HP + "` = ?,`" + MP + "` = ?,`" + CP
- + "` = ?,`" + POINT_X + "` = ?,`" + POINT_Y + "` = ?,`"
- + POINT_Z + "` = ?,`" + POINT_ANGLE + "` = ?,`"
- + APPEARANCE_HAIR_STYLE + "` = ?,`"
- + APPEARANCE_HAIR_COLOR + "` = ?,`" + APPEARANCE_FACE
- + "` = ? WHERE `" + CHAR_ID + "` = ?";
+ protected void query(SQLUpdateClause q, L2Character o) {
+ q.where(e.characterId.eq(o.getID().getID()));
}
@Override
- protected void parametize(PreparedStatement st,
- L2Character character) throws SQLException {
- final CharacterAppearance appearance = character
- .getAppearance();
- int i = 1;
-
- // SET
- st.setString(i++, character.getAccountID().getID());
- if (character.getClanID() != null)
- st.setInt(i++, character.getClanID().getID());
- else
- st.setNull(i++, Types.INTEGER);
-
- st.setString(i++, character.getName());
-
- st.setString(i++, character.getRace().name());
- st.setString(i++, character.getCharacterClass().name());
- st.setString(i++, character.getSex().name());
-
- st.setInt(i++, character.getLevel());
- st.setLong(i++, character.getExperience());
- st.setInt(i++, character.getSP());
-
- st.setDouble(i++, character.getHP());
- st.setDouble(i++, character.getMP());
- st.setDouble(i++, character.getCP());
-
- // position
- st.setInt(i++, character.getPoint().getX());
- st.setInt(i++, character.getPoint().getY());
- st.setInt(i++, character.getPoint().getZ());
- st.setDouble(i++, character.getPoint().getAngle());
-
- // appearance
- st.setString(i++, appearance.getHairStyle().name());
- st.setString(i++, appearance.getHairColor().name());
- st.setString(i++, appearance.getFace().name());
-
- // WHERE
- st.setInt(i++, character.getID().getID());
+ protected void map(SQLUpdateClause q, L2Character o) {
+ q.set(e.accountId, o.getAccountID().getID())
+ .set(e.clanId,
+ (o.getClanID() != null ? o.getClanID().getID()
+ : null))
+ .set(e.name, o.getName())
+ .set(e.race, o.getRace())
+ .set(e.characterClass, o.getCharacterClass())
+ .set(e.sex, o.getSex())
+ .set(e.level, o.getLevel())
+ .set(e.experience, o.getExperience())
+ .set(e.sp, o.getSP())
+ .set(e.hp, o.getHP())
+ .set(e.mp, o.getMP())
+ .set(e.cp, o.getCP())
+ .set(e.pointX, o.getPoint().getX())
+ .set(e.pointY, o.getPoint().getY())
+ .set(e.pointZ, o.getPoint().getZ())
+ .set(e.pointAngle, o.getPoint().getAngle())
+ .set(e.appearanceHairStyle,
+ o.getAppearance().getHairStyle())
+ .set(e.appearanceHairColor,
+ o.getAppearance().getHairColor())
+ .set(e.apperanceFace, o.getAppearance().getFace());
}
});
}
@Override
public int deleteObjects(L2Character... characters) {
- return database.query(new InsertUpdateQuery(characters) {
+ return database.query(new DeleteQuery(
+ QCharacter.character, characters) {
@Override
- protected String query() {
- return "DELETE FROM `" + TABLE + "` WHERE `" + CHAR_ID
- + "` = ?";
- }
-
- @Override
- protected void parametize(PreparedStatement st,
- L2Character character) throws SQLException {
- st.setInt(1, character.getID().getID());
+ protected void query(SQLDeleteClause q, L2Character o) {
+ q.where(e.characterId.eq(o.getID().getID()));
}
});
}
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 14af02728..0232df45c 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
@@ -16,9 +16,6 @@
*/
package com.l2jserver.service.database.jdbc;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
import java.util.List;
import com.google.inject.Inject;
@@ -26,17 +23,18 @@ import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterFriendDAO;
import com.l2jserver.model.game.CharacterFriend;
import com.l2jserver.model.id.FriendID;
-import com.l2jserver.model.id.object.CharacterID;
-import com.l2jserver.model.id.object.provider.CharacterIDProvider;
-import com.l2jserver.model.id.provider.FriendIDProvider;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.character.CharacterFriendList;
-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;
+import com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.DeleteQuery;
+import com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.InsertQuery;
+import com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.SelectListQuery;
+import com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.SelectSingleQuery;
+import com.l2jserver.service.database.mapper.CharacterFriendMapper;
+import com.l2jserver.service.database.model.QCharacterFriend;
+import com.mysema.query.sql.AbstractSQLQuery;
+import com.mysema.query.sql.dml.SQLDeleteClause;
+import com.mysema.query.sql.dml.SQLInsertClause;
/**
* {@link CharacterFriendDAO} implementation for JDBC
@@ -47,107 +45,47 @@ public class JDBCCharacterFriendDAO extends
AbstractJDBCDAO implements
CharacterFriendDAO {
/**
- * The {@link FriendID} provider
+ * The {@link CharacterFriend} mapper
*/
- private final FriendIDProvider idProvider;
- /**
- * The {@link CharacterID} provider
- */
- private final CharacterIDProvider charIdProvider;
-
- /**
- * Character table name
- */
- public static final String TABLE = "character_friend";
- // FIELDS
- public static final String CHAR_ID = JDBCCharacterDAO.CHAR_ID;
- public static final String CHAR_ID_FRIEND = JDBCCharacterDAO.CHAR_ID
- + "_friend";
+ private final CharacterFriendMapper mapper;
/**
* @param database
* the database service
- * @param idProvider
- * the frind id provider
- * @param charIdProvider
- * the character id provider
+ * @param mapper
+ * the character friend mapper
*/
@Inject
public JDBCCharacterFriendDAO(DatabaseService database,
- final FriendIDProvider idProvider,
- CharacterIDProvider charIdProvider) {
+ CharacterFriendMapper mapper) {
super(database);
- this.idProvider = idProvider;
- this.charIdProvider = charIdProvider;
+ this.mapper = mapper;
}
- /**
- * The {@link Mapper} for {@link FriendID}
- */
- private final Mapper idMapper = new Mapper() {
- @Override
- public FriendID map(ResultSet rs) throws SQLException {
- final CharacterID characterId = charIdProvider.resolveID(rs
- .getInt(CHAR_ID));
- final CharacterID friendId = charIdProvider.resolveID(rs
- .getInt(CHAR_ID_FRIEND));
- return idProvider.createID(characterId, friendId);
- }
- };
-
- /**
- * The {@link Mapper} for {@link CharacterFriend}
- */
- private final Mapper mapper = new CachedMapper(
- database, idMapper) {
- @Override
- protected CharacterFriend map(FriendID id, ResultSet rs)
- throws SQLException {
- return new CharacterFriend(id);
- }
- };
-
@Override
public CharacterFriend select(final FriendID id) {
- return database.query(new SelectSingleQuery() {
- @Override
- protected String query() {
- return "SELECT * FROM `" + TABLE + "` WHERE `" + CHAR_ID
- + "` = ? AND `" + CHAR_ID_FRIEND + "` = ?";
- }
-
- @Override
- protected void parametize(PreparedStatement st) throws SQLException {
- st.setInt(1, id.getID1().getID());
- st.setInt(2, id.getID2().getID());
- }
-
- @Override
- protected Mapper mapper() {
- return mapper;
- }
- });
+ return database
+ .query(new SelectSingleQuery(
+ QCharacterFriend.characterFriend, mapper) {
+ @Override
+ protected void query(AbstractSQLQuery> q,
+ QCharacterFriend e) {
+ q.where(e.characterId.eq(id.getCharacterID().getID())
+ .and(e.characterIdFriend.eq(id.getFriendID()
+ .getID())));
+ }
+ });
}
@Override
public void load(final L2Character character) {
final List list = database
- .query(new SelectListQuery() {
+ .query(new SelectListQuery(
+ QCharacterFriend.characterFriend, mapper) {
@Override
- protected String query() {
- return "SELECT * FROM `" + TABLE + "` WHERE `"
- + CHAR_ID + "` = ?";
- }
-
- @Override
- protected void parametize(PreparedStatement st)
- throws SQLException {
- st.setInt(1, character.getID().getID());
- }
-
- @Override
- protected Mapper mapper() {
- return mapper;
+ protected void query(AbstractSQLQuery> q,
+ QCharacterFriend e) {
+ q.where(e.characterId.eq(character.getID().getID()));
}
});
character.getFriendList().load(list);
@@ -155,35 +93,25 @@ public class JDBCCharacterFriendDAO extends
@Override
public List selectIDs() {
- return database.query(new SelectListQuery() {
+ return database.query(new SelectListQuery(
+ QCharacterFriend.characterFriend, mapper.getIDMapper()) {
@Override
- protected String query() {
- return "SELECT * FROM `" + TABLE + "`";
- }
-
- @Override
- protected Mapper mapper() {
- return idMapper;
+ protected void query(AbstractSQLQuery> q, QCharacterFriend e) {
}
});
}
@Override
public int insertObjects(CharacterFriend... friends) {
- return database.query(new InsertUpdateQuery(friends) {
- @Override
- protected String query() {
- return "INSERT INTO `" + TABLE + "` (`" + CHAR_ID + "`,`"
- + CHAR_ID_FRIEND + "`) VALUES(?,?)";
- }
-
- @Override
- protected void parametize(PreparedStatement st,
- CharacterFriend friend) throws SQLException {
- st.setInt(1, friend.getCharacterID().getID());
- st.setInt(2, friend.getFriendID().getID());
- }
- });
+ return database
+ .query(new InsertQuery(
+ QCharacterFriend.characterFriend, friends) {
+ @Override
+ protected void map(SQLInsertClause q, CharacterFriend o) {
+ q.set(e.characterId, o.getCharacterID().getID()).set(
+ e.characterIdFriend, o.getFriendID().getID());
+ }
+ });
}
@Override
@@ -195,20 +123,17 @@ public class JDBCCharacterFriendDAO extends
@Override
public int deleteObjects(CharacterFriend... friends) {
- return database.query(new InsertUpdateQuery(friends) {
- @Override
- protected String query() {
- return "DELETE FROM `" + TABLE + "` WHERE `" + CHAR_ID
- + "` = ?,`" + CHAR_ID_FRIEND + "` = ?";
- }
-
- @Override
- protected void parametize(PreparedStatement st,
- CharacterFriend friend) throws SQLException {
- st.setInt(1, friend.getCharacterID().getID());
- st.setInt(2, friend.getFriendID().getID());
- }
- });
+ return database
+ .query(new DeleteQuery(
+ QCharacterFriend.characterFriend, friends) {
+ @Override
+ protected void query(SQLDeleteClause q, CharacterFriend o) {
+ q.where(e.characterId.eq(
+ o.getID().getCharacterID().getID()).and(
+ e.characterIdFriend.eq(o.getID().getFriendID()
+ .getID())));
+ }
+ });
}
@Override
@@ -228,7 +153,7 @@ public class JDBCCharacterFriendDAO extends
}
return true;
}
-
+
@Override
protected CharacterFriend[] wrap(Model>... objects) {
final CharacterFriend[] array = new CharacterFriend[objects.length];
diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCCharacterShortcutDAO.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCCharacterShortcutDAO.java
index ef4d6a6c9..6424812e8 100644
--- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCCharacterShortcutDAO.java
+++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/database/jdbc/JDBCCharacterShortcutDAO.java
@@ -16,32 +16,27 @@
*/
package com.l2jserver.service.database.jdbc;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
import java.util.List;
import com.google.inject.Inject;
import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterFriendDAO;
import com.l2jserver.model.dao.CharacterShortcutDAO;
-import com.l2jserver.model.game.CharacterFriend;
import com.l2jserver.model.game.CharacterShortcut;
-import com.l2jserver.model.game.CharacterShortcut.ShortcutType;
import com.l2jserver.model.id.CharacterShortcutID;
-import com.l2jserver.model.id.FriendID;
-import com.l2jserver.model.id.object.CharacterID;
-import com.l2jserver.model.id.object.ItemID;
-import com.l2jserver.model.id.object.provider.CharacterIDProvider;
-import com.l2jserver.model.id.object.provider.ItemIDProvider;
-import com.l2jserver.model.id.provider.CharacterShortcutIDProvider;
import com.l2jserver.model.world.L2Character;
-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;
+import com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.DeleteQuery;
+import com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.InsertQuery;
+import com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.SelectListQuery;
+import com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.SelectSingleQuery;
+import com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.UpdateQuery;
+import com.l2jserver.service.database.mapper.CharacterShortcutMapper;
+import com.l2jserver.service.database.model.QCharacterShortcut;
+import com.mysema.query.sql.AbstractSQLQuery;
+import com.mysema.query.sql.dml.SQLDeleteClause;
+import com.mysema.query.sql.dml.SQLInsertClause;
+import com.mysema.query.sql.dml.SQLUpdateClause;
/**
* {@link CharacterFriendDAO} implementation for JDBC
@@ -51,239 +46,114 @@ import com.l2jserver.service.database.DatabaseService;
public class JDBCCharacterShortcutDAO extends
AbstractJDBCDAO implements
CharacterShortcutDAO {
- /**
- * The {@link CharacterShortcutID} provider
- */
- private final CharacterShortcutIDProvider idProvider;
- /**
- * The {@link CharacterID} provider
- */
- private final CharacterIDProvider charIdProvider;
- /**
- * The {@link ItemID} provider
- */
- private final ItemIDProvider itemIdProvider;
-
- /**
- * Character table name
- */
- public static final String TABLE = "character_shortcut";
- // FIELDS
- public static final String SHORTCUT_ID = "shortcut_id";
- public static final String CHAR_ID = JDBCCharacterDAO.CHAR_ID;
- public static final String TYPE = "type";
- public static final String SLOT = "slot";
- public static final String PAGE = "page";
-
- // item id, skill id (pretty much anything!)
- public static final String OBJECT_ID = "object_id";
- public static final String SKILL_LEVEL = "skill_level";
+ private final CharacterShortcutMapper mapper;
/**
* @param database
* the database service
- * @param idProvider
- * the frind id provider
- * @param charIdProvider
- * the character id provider
- * @param itemIdProvider
- * the item id provider
+ * @param mapper
+ * the {@link CharacterShortcut} mapper
*/
@Inject
public JDBCCharacterShortcutDAO(DatabaseService database,
- final CharacterShortcutIDProvider idProvider,
- CharacterIDProvider charIdProvider, ItemIDProvider itemIdProvider) {
+ CharacterShortcutMapper mapper) {
super(database);
- this.idProvider = idProvider;
- this.charIdProvider = charIdProvider;
- this.itemIdProvider = itemIdProvider;
+ this.mapper = mapper;
}
- /**
- * The {@link Mapper} for {@link FriendID}
- */
- private final Mapper idMapper = new Mapper() {
- @Override
- public CharacterShortcutID map(ResultSet rs) throws SQLException {
- return idProvider.resolveID(rs.getInt(SHORTCUT_ID));
- }
- };
-
- /**
- * The {@link Mapper} for {@link CharacterFriend}
- */
- private final Mapper mapper = new CachedMapper(
- database, idMapper) {
- @Override
- protected CharacterShortcut map(CharacterShortcutID id, ResultSet rs)
- throws SQLException {
- final CharacterShortcut shortcut = new CharacterShortcut();
- shortcut.setID(id);
- final CharacterID charId = charIdProvider.resolveID(rs
- .getInt(CHAR_ID));
- shortcut.setCharacterID(charId);
-
- // resolve type
- final ShortcutType type = ShortcutType.valueOf(rs.getString(TYPE));
- shortcut.setType(type);
- switch (type) {
- case ITEM:
- final ItemID itemId = itemIdProvider.resolveID(rs
- .getInt(OBJECT_ID));
- shortcut.setItemID(itemId);
- break;
- }
-
- shortcut.setPage(rs.getInt(PAGE));
- shortcut.setSlot(rs.getInt(SLOT));
-
- return shortcut;
- }
- };
-
@Override
public CharacterShortcut select(final CharacterShortcutID id) {
- return database.query(new SelectSingleQuery() {
- @Override
- protected String query() {
- return "SELECT * FROM `" + TABLE + "` WHERE `" + SHORTCUT_ID
- + "` = ?";
- }
-
- @Override
- protected void parametize(PreparedStatement st) throws SQLException {
- st.setInt(1, id.getID());
- }
-
- @Override
- protected Mapper mapper() {
- return mapper;
- }
- });
+ return database
+ .query(new SelectSingleQuery(
+ QCharacterShortcut.characterShortcut, mapper) {
+ @Override
+ protected void query(AbstractSQLQuery> q,
+ QCharacterShortcut e) {
+ q.where(e.shortcutId.eq(id.getID()));
+ }
+ });
}
@Override
public List selectByCharacter(final L2Character character) {
- return database.query(new SelectListQuery() {
- @Override
- protected String query() {
- return "SELECT * FROM `" + TABLE + "` WHERE `" + CHAR_ID
- + "` = ?";
- }
-
- @Override
- protected void parametize(PreparedStatement st) throws SQLException {
- st.setInt(1, character.getID().getID());
- }
-
- @Override
- protected Mapper mapper() {
- return mapper;
- }
- });
+ return database
+ .query(new SelectListQuery(
+ QCharacterShortcut.characterShortcut, mapper) {
+ @Override
+ protected void query(AbstractSQLQuery> q,
+ QCharacterShortcut e) {
+ q.where(e.characterId.eq(character.getID().getID()));
+ }
+ });
}
@Override
public List selectIDs() {
- return database.query(new SelectListQuery