1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-06 07:32:46 +00:00

Implements a type-safe and java based new DAO model

This commit is contained in:
2011-12-22 17:18:12 -02:00
parent 84033a0bb9
commit 5b658a2eea
52 changed files with 2847 additions and 4695 deletions

View File

@@ -73,11 +73,6 @@
<artifactId>commons-dbcp</artifactId> <artifactId>commons-dbcp</artifactId>
<version>1.4</version> <version>1.4</version>
</dependency> </dependency>
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-core</artifactId>
<version>1.0rc7</version>
</dependency>
<!-- cache --> <!-- cache -->
<dependency> <dependency>
<groupId>net.sf.ehcache</groupId> <groupId>net.sf.ehcache</groupId>
@@ -115,5 +110,10 @@
<artifactId>commons-math</artifactId> <artifactId>commons-math</artifactId>
<version>2.2</version> <version>2.2</version>
</dependency> </dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-sql</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -118,8 +118,8 @@ public abstract class AbstractDAO<T extends Model<?>, I extends ID<?>>
} }
@Override @Override
public void insert(T object) { public int insert(T object) {
insertObjects(wrap(object)); return insertObjects(wrap(object));
} }
@Override @Override
@@ -134,8 +134,8 @@ public abstract class AbstractDAO<T extends Model<?>, I extends ID<?>>
} }
@Override @Override
public void update(T object) { public int update(T object) {
updateObjects(wrap(object)); return updateObjects(wrap(object));
} }
@Override @Override

View File

@@ -1,702 +0,0 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
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.
*
* <h1>Internal specification</h1> <h2>The {@link Query} object</h2>
*
* 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.
*
* <h2>The {@link Mapper} object</h2>
*
* 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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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<Object, Model<?>> 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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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<Model<?>, ?> 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<Integer> transactionAsync(
final TransactionExecutor executor) {
return threadService.async(new AbstractTask<Integer>() {
@Override
public Integer call() throws Exception {
return transaction(executor);
}
});
}
/**
* Executes an <tt>query</tt> in the database.
*
* @param <T>
* the query return type
* @param query
* the query
* @return an instance of <tt>T</tt>
*/
public <T> T query(Query<T> 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 <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <R>
* the return type
*/
public interface Query<R> {
/**
* Execute the query in <tt>conn</tt>
*
* @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:
* <ul>
* <li>INSERT INTO</li>
* <li>UPDATE</li>
* <li>DELETE FROM</li>
* </ul>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <T>
* the query return type
*/
public static abstract class InsertUpdateQuery<T> implements Query<Integer> {
/**
* The logger
*/
private final Logger log = LoggerFactory
.getLogger(InsertUpdateQuery.class);
/**
* The iterator
*/
private final Iterator<T> iterator;
/**
* Creates a new query for <tt>objects</tt>
*
* @param objects
* the object list
*/
@SafeVarargs
public InsertUpdateQuery(T... objects) {
this(new ArrayIterator<T>(objects));
}
/**
* Create a new query for objects in <tt>iterator</tt>
*
* @param iterator
* the object iterator
*/
public InsertUpdateQuery(Iterator<T> 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<OQueryContextNative> query = createQuery(
database, object);
final ODocument document;
if (query != null) {
List<ODocument> 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 <b>prepared</b> query for execution
*
* @param database
* the database
* @param object
* the object that is being updated
*
* @return the <b>prepared</b> query. If <tt>null</tt> is returned a
* insert query will be performed.
*/
protected abstract ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database, T object);
/**
* Set the parameters in <tt>document</tt> for <tt>object</tt>. The
* object can be removed calling {@link ODocument#delete()} and
* returning <tt>null</tt>
*
* @param document
* the document
* @param object
* the object
* @return the updated document. Can be <tt>null</tt>
* @throws SQLException
* if any SQL error occur
*/
protected abstract ODocument update(ODocument document, T object)
throws SQLException;
/**
* Set the parameters for in <tt>statement</tt> for <tt>object</tt>
*
* @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 <tt>T</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <T>
* the query return type
*/
public static abstract class SelectListQuery<T> implements Query<List<T>> {
/**
* The logger
*/
private final Logger log = LoggerFactory
.getLogger(SelectListQuery.class);
@Override
public List<T> query(ODatabaseDocumentTx database) throws SQLException {
Preconditions.checkNotNull(database, "database");
log.debug("Starting SELECT List<?> query execution");
List<ODocument> result = database.query(createQuery(database));
final List<T> list = CollectionFactory.newList();
final Mapper<T> 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 <b>prepared</b> query for execution
*
* @param database
* the database
*
* @return the <b>prepared</b> query
*/
protected abstract ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database);
/**
* Return the mapper that will bind {@link ResultSet} objects into an
* <tt>T</tt> object instance. The mapper will need to create the object
* instance.
* <p>
* <b>Note</b>: 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<T> mapper();
}
/**
* An select query that returns a single object of type <tt>T</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <T>
* the query return type
*/
public static abstract class SelectSingleQuery<T> implements Query<T> {
/**
* 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<ODocument> result = database.query(createQuery(database));
final Mapper<T> 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 <b>prepared</b> query for execution
*
* @param database
* the database
*
* @return the <b>prepared</b> query
*/
protected abstract ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database);
/**
* Return the mapper that will bind {@link ResultSet} objects into an
* <tt>T</tt> object instance. The mapper will need to create the object
* instance.
* <p>
* <b>Note</b>: 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<T> mapper();
}
/**
* The {@link Mapper} maps an {@link ResultSet} into an object <tt>T</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <T>
* the object type
*/
public interface Mapper<T> {
/**
* Map the result set value into an object.
* <p>
* <b>Note</b>: 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 <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <T>
* the object type
* @param <I>
* the id type
*/
public abstract static class CachedMapper<T extends Model<?>, I extends ID<?>>
implements Mapper<T> {
/**
* 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<I> idMapper;
/**
* Creates a new instance
*
* @param database
* the database service
* @param idMapper
* the {@link ID} {@link Mapper}
*/
public CachedMapper(AbstractOrientDatabaseService database,
Mapper<I> 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;
}
}

View File

@@ -180,8 +180,9 @@ public interface DataAccessObject<O extends Model<?>, I extends ID<?>> extends
* *
* @param object * @param object
* the 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 * Inserts several instances in the database using a transaction (if
@@ -210,8 +211,9 @@ public interface DataAccessObject<O extends Model<?>, I extends ID<?>> extends
* *
* @param object * @param object
* the 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 * Updates several instances in the database using a transaction (if

View File

@@ -14,31 +14,40 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>. * along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.l2jserver.service.database.orientdb; package com.l2jserver.service.database;
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;
/** /**
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
* @param <T>
* the model type
* @param <I>
* the id type
*/ */
public abstract class AbstractOrientDBDAO<T extends Model<?>, I extends ID<?>> public class DatabaseMappingException extends DatabaseException {
extends AbstractDAO<T, I> { private static final long serialVersionUID = 1L;
protected final AbstractOrientDatabaseService database;
public DatabaseMappingException() {
super();
}
/** /**
* @param database * @param message
* the database instance * the message
* @param cause
* the root cause
*/ */
protected AbstractOrientDBDAO(DatabaseService database) { public DatabaseMappingException(String message, Throwable cause) {
super(database); }
this.database = (AbstractOrientDatabaseService) database;
/**
* @param message
* the message
*/
public DatabaseMappingException(String message) {
super(message);
}
/**
* @param cause
* the root cause
*/
public DatabaseMappingException(Throwable cause) {
super(cause);
} }
} }

View File

@@ -16,6 +16,8 @@
*/ */
package com.l2jserver.service.database; 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.Service;
import com.l2jserver.service.ServiceConfiguration; import com.l2jserver.service.ServiceConfiguration;
import com.l2jserver.service.configuration.Configuration; import com.l2jserver.service.configuration.Configuration;
@@ -98,4 +100,60 @@ public interface DatabaseService extends Service {
*/ */
int perform(); int perform();
} }
/**
* Checks for the cached version of the object
*
* @param <I>
* the {@link ID} type
* @param <O>
* the {@link Model} type
*
* @param id
* the object ID
* @return the cached version, if any
*/
<I extends ID<?>, O extends Model<?>> Object getCachedObject(I id);
/**
* Checks for the cached version of the object
*
* @param <I>
* the {@link ID} type
* @param <O>
* the {@link Model} type
*
* @param id
* the object ID
* @return true if has an cached version,
*/
<I extends ID<?>, O extends Model<?>> boolean hasCachedObject(I id);
/**
* Updates an cache object
*
* @param <I>
* the {@link ID} type
* @param <O>
* the {@link Model} type
*
* @param id
* the cache key
* @param value
* the model value
*/
<I extends ID<?>, O extends Model<?>> void updateCache(I id, O value);
/**
* Removes an cached object
*
* @param <I>
* the {@link ID} type
* @param <O>
* the {@link Model} type
*
* @param id
* the object id
*/
<I extends ID<?>, O extends Model<?>> void removeCache(I id);
} }

View File

@@ -0,0 +1,30 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.dao;
import com.mysema.query.types.Path;
/**
* Database column used to read data
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface DatabaseRow {
<T> T get(Path<T> path);
<T> boolean isNull(Path<T> path);
}

View File

@@ -0,0 +1,30 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.dao;
import com.mysema.query.sql.RelationalPathBase;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
* @param <O>
* the object type returned by this mapper
* @param <E>
* the entity type
*/
public interface Mapper<O, E extends RelationalPathBase<?>> {
O map(E entity, DatabaseRow row);
}

View File

@@ -21,7 +21,6 @@ import com.l2jserver.model.Model;
import com.l2jserver.model.id.ID; import com.l2jserver.model.id.ID;
import com.l2jserver.service.database.AbstractDAO; import com.l2jserver.service.database.AbstractDAO;
import com.l2jserver.service.database.DatabaseService; import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.AbstractJDBCDatabaseService;
/** /**
* {@link AbstractDAO} for JDBC DAO implementation * {@link AbstractDAO} for JDBC DAO implementation

View File

@@ -0,0 +1,848 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
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.
*
* <h1>Internal specification</h1> <h2>The {@link Query} object</h2>
*
* 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.
*
* <h2>The {@link Mapper} object</h2>
*
* The {@link Mapper} object maps an JDBC {@link DatabaseRow} into an Java
* {@link Object}.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
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<ID<?>, 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<Connection> 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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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<Model<?>, ?> dao = (DataAccessObject<Model<?>, ?>) 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<Integer> transactionAsync(
final TransactionExecutor executor) {
return threadService.async(new AbstractTask<Integer>() {
@Override
public Integer call() throws Exception {
return transaction(executor);
}
});
}
/**
* Executes an <tt>query</tt> in the database.
*
* @param <T>
* the query return type
* @param query
* the query
* @return an instance of <tt>T</tt>
* @throws DatabaseException
* if any exception occur (can have nested {@link SQLException})
*/
public <T> T query(Query<T> 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<Connection>() {
@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<Connection> 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 <I extends ID<?>, O extends Model<?>> O getCachedObject(I id) {
Preconditions.checkNotNull(id, "id");
log.debug("Fetching cached object {}", id);
return (O) objectCache.get(id);
}
@Override
public <I extends ID<?>, O extends Model<?>> boolean hasCachedObject(I id) {
Preconditions.checkNotNull(id, "id");
log.debug("Locating cached object {}", id);
return objectCache.contains(id);
}
@Override
public <I extends ID<?>, 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 <I extends ID<?>, 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 <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <R>
* the return type
*/
public interface Query<R> {
/**
* Execute the query in <tt>conn</tt>
*
* @param factory
* the query factory (database specific)
* @return the query return value
*/
R query(SQLQueryFactory<? extends AbstractSQLQuery<?>, ?, ?, ?, ?, ?> factory);
}
public static abstract class AbstractQuery<R> implements Query<R> {
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<O, E extends RelationalPathBase<?>, K>
extends AbstractQuery<Integer> {
private final Iterator<O> iterator;
private final Path<K> 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<K> primaryKey, Iterator<O> 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<O> 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<K> 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<O, E extends RelationalPathBase<?>>
extends AbstractQuery<Integer> {
private final Iterator<O> iterator;
protected final E e;
/**
* @param entity
* the entity type
* @param iterator
* the objects to be inserted
*/
public UpdateQuery(E entity, Iterator<O> 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<O, E extends RelationalPathBase<?>>
extends AbstractQuery<Integer> {
private final Iterator<O> iterator;
protected final E e;
/**
* @param entity
* the entity type
* @param iterator
* the objects to be inserted
*/
public DeleteQuery(E entity, Iterator<O> 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<R, O, E extends RelationalPathBase<?>>
extends AbstractQuery<R> {
protected final E entity;
protected final Mapper<O, E> mapper;
/**
* @param entity
* the entity type
* @param mapper
* the object mapper
*/
public AbstractSelectQuery(E entity, Mapper<O, E> 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<O, E extends RelationalPathBase<?>>
extends AbstractSelectQuery<O, O, E> {
/**
* @param entity
* the entity
* @param mapper
* the mapper
*/
public SelectSingleQuery(E entity, Mapper<O, E> mapper) {
super(entity, mapper);
}
@Override
protected final O perform(AbstractSQLQuery<?> select) {
final List<Object[]> 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<O, E extends RelationalPathBase<?>>
extends AbstractSelectQuery<List<O>, O, E> {
/**
* @param entity
* the entity
* @param mapper
* the mapper
*/
public SelectListQuery(E entity, Mapper<O, E> mapper) {
super(entity, mapper);
}
@Override
protected final List<O> perform(AbstractSQLQuery<?> select) {
final List<Object[]> results = select.list(entity.all());
final JDBCDatabaseRow row = new JDBCDatabaseRow(entity);
final List<O> 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;
}
}
}

View File

@@ -0,0 +1,76 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
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 <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class JDBCDatabaseRow implements DatabaseRow {
@SuppressWarnings("unused")
private final RelationalPathBase<?> entity;
private final List<Path<?>> 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> T get(Path<T> path) {
// this cast should be safe!
return (T) row[indexOf(path)];
}
@Override
public <T> boolean isNull(Path<T> path) {
return row[indexOf(path)] == null;
}
private int indexOf(Path<?> path) {
return paths.indexOf(path);
}
public void setRow(Object[] row) {
this.row = row;
}
}

View File

@@ -18,10 +18,11 @@ package com.l2jserver.util.geometry;
import org.apache.commons.math.geometry.Vector3D; import org.apache.commons.math.geometry.Vector3D;
/** /**
* Represents an coordinate in the game world. * Represents an coordinate in the game world.
* <p> * <p>
* Each coordinate has 3 points: x, y and z. * Each coordinate has 3 axis: x, y and z.
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */

View File

@@ -27,6 +27,16 @@
driver library must be available in the JVM classpath. --> driver library must be available in the JVM classpath. -->
<driver>com.mysql.jdbc.Driver</driver> <driver>com.mysql.jdbc.Driver</driver>
<!-- The SQLTemplates provides several low-level SQL management. Templates
are database dependent. -->
<templates>com.mysema.query.sql.MySQLTemplates</templates>
<!-- The query factory provides an class that allows to convert Java
code to SQL code and parses database results into more easily managed Java
code. -->
<queryFactory>com.mysema.query.sql.mysql.MySQLQueryFactory
</queryFactory>
<!-- The username used to login into the database. NOTE: Try not use <!-- The username used to login into the database. NOTE: Try not use
"root" in production servers for security reasons. --> "root" in production servers for security reasons. -->
<username>l2j</username> <username>l2j</username>

View File

@@ -26,6 +26,16 @@
<!-- The driver used to connect to the database. Please note that the <!-- The driver used to connect to the database. Please note that the
driver library must be available in the JVM classpath. --> driver library must be available in the JVM classpath. -->
<driver>com.mysql.jdbc.Driver</driver> <driver>com.mysql.jdbc.Driver</driver>
<!-- The SQLTemplates provides several low-level SQL management. Templates
are database dependent. -->
<templates>com.mysema.query.sql.MySQLTemplates</templates>
<!-- The query factory provides an class that allows to convert Java
code to SQL code and parses database results into more easily managed Java
code. -->
<queryFactory>com.mysema.query.sql.mysql.MySQLQueryFactory
</queryFactory>
<!-- The username used to login into the database. NOTE: Try not use <!-- The username used to login into the database. NOTE: Try not use
"root" in production servers for security reasons. --> "root" in production servers for security reasons. -->

View File

@@ -21,7 +21,6 @@
<descriptors> <descriptors>
<descriptor>src/main/assembly/distribution-mysql5-bin.xml</descriptor> <descriptor>src/main/assembly/distribution-mysql5-bin.xml</descriptor>
<descriptor>src/main/assembly/distribution-h2-bin.xml</descriptor> <descriptor>src/main/assembly/distribution-h2-bin.xml</descriptor>
<descriptor>src/main/assembly/distribution-orientdb-bin.xml</descriptor>
<descriptor>src/main/assembly/distribution-derby-bin.xml</descriptor> <descriptor>src/main/assembly/distribution-derby-bin.xml</descriptor>
<descriptor>src/main/assembly/distribution-src.xml</descriptor> <descriptor>src/main/assembly/distribution-src.xml</descriptor>
</descriptors> </descriptors>
@@ -83,12 +82,6 @@
<version>10.8.2.2</version> <version>10.8.2.2</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-core</artifactId>
<version>1.0rc7</version>
<type>jar</type>
</dependency>
<!-- cache --> <!-- cache -->
<dependency> <dependency>
<groupId>net.sf.ehcache</groupId> <groupId>net.sf.ehcache</groupId>

View File

@@ -48,7 +48,6 @@
<excludes> <excludes>
<exclude>mysql:*</exclude> <exclude>mysql:*</exclude>
<exclude>com.h2database:*</exclude> <exclude>com.h2database:*</exclude>
<exclude>com.orientechnologies:*</exclude>
</excludes> </excludes>
</dependencySet> </dependencySet>
</dependencySets> </dependencySets>

View File

@@ -48,7 +48,6 @@
<excludes> <excludes>
<exclude>mysql:*</exclude> <exclude>mysql:*</exclude>
<exclude>org.apache.derby:*</exclude> <exclude>org.apache.derby:*</exclude>
<exclude>com.orientechnologies:*</exclude>
</excludes> </excludes>
</dependencySet> </dependencySet>
</dependencySets> </dependencySets>

View File

@@ -47,7 +47,6 @@
<excludes> <excludes>
<exclude>com.h2database:*</exclude> <exclude>com.h2database:*</exclude>
<exclude>org.apache.derby:*</exclude> <exclude>org.apache.derby:*</exclude>
<exclude>com.orientechnologies:*</exclude>
</excludes> </excludes>
</dependencySet> </dependencySet>
</dependencySets> </dependencySets>

View File

@@ -1,55 +0,0 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>orientdb-bin</id>
<formats>
<format>zip</format>
</formats>
<baseDirectory></baseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>data/**</include>
</includes>
<excludes>
<exclude>.gitignore</exclude>
<exclude>data/cache/**</exclude>
<exclude>data/pathing.db</exclude>
<exclude>data/database/derby/**</exclude>
<exclude>data/database/h2/**</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>${project.basedir}/distribution/global</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.basedir}/distribution/sql</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
<files>
<file>
<source>${project.build.directory}/${project.artifactId}-${project.version}.jar</source>
<outputDirectory>/</outputDirectory>
<destName>l2jserver2.jar</destName>
<fileMode>0755</fileMode>
</file>
</files>
<dependencySets>
<dependencySet>
<outputDirectory>/libs</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>false</unpack>
<scope>runtime</scope>
<excludes>
<exclude>mysql:*</exclude>
<exclude>com.h2database:*</exclude>
<exclude>org.apache.derby:*</exclude>
</excludes>
</dependencySet>
</dependencySets>
</assembly>

View File

@@ -16,50 +16,48 @@
*/ */
package com.l2jserver.service.database; package com.l2jserver.service.database;
import java.sql.ResultSet;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.l2jserver.model.Model; import com.l2jserver.model.game.CharacterShortcut.ShortcutType;
import com.l2jserver.model.id.ID; 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.AbstractService.Depends;
import com.l2jserver.service.cache.CacheService; import com.l2jserver.service.cache.CacheService;
import com.l2jserver.service.configuration.ConfigurationService; import com.l2jserver.service.configuration.ConfigurationService;
import com.l2jserver.service.core.LoggingService; import com.l2jserver.service.core.LoggingService;
import com.l2jserver.service.core.threading.ThreadService; 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.l2jserver.service.game.template.TemplateService;
import com.mysema.query.sql.types.EnumByNameType;
/** /**
* This is an implementation of {@link DatabaseService} that provides an layer * This is an implementation of {@link DatabaseService} that provides an layer
* to JDBC. * to JDBC.
* *
* <h1>Internal specification</h1> <h2>The * <h1>Internal specification</h1> <h2>The
* {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Query * {@link com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.Query
* Query} object</h2> * Query} object</h2>
* *
* If you wish to implement a new {@link DataAccessObject} you should try not * 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 * Query} object directly because it only provides low level access to the JDBC
* architecture. Instead, you could use an specialized class, like * 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} , * InsertUpdateQuery} ,
* {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.SelectListQuery * {@link com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.SelectListQuery
* SelectListQuery} or * 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 * 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. * Query} class directly.
* *
* <h2>The
* {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Mapper
* Mapper} object</h2>
*
* 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 <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
@Depends({ LoggingService.class, CacheService.class, @Depends({ LoggingService.class, CacheService.class,
@@ -80,6 +78,20 @@ public class GameServerJDBCDatabaseService extends AbstractJDBCDatabaseService
public GameServerJDBCDatabaseService(ConfigurationService configService, public GameServerJDBCDatabaseService(ConfigurationService configService,
CacheService cacheService, ThreadService threadService, CacheService cacheService, ThreadService threadService,
DAOResolver daoResolver) { DAOResolver daoResolver) {
super(configService, cacheService, threadService, daoResolver); super(
configService,
cacheService,
threadService,
daoResolver,
new EnumByNameType<CharacterRace>(CharacterRace.class),
new EnumByNameType<CharacterClass>(CharacterClass.class),
new EnumByNameType<ActorSex>(ActorSex.class),
new EnumByNameType<CharacterHairColor>(CharacterHairColor.class),
new EnumByNameType<CharacterHairStyle>(CharacterHairStyle.class),
new EnumByNameType<CharacterFace>(CharacterFace.class),
new EnumByNameType<ShortcutType>(ShortcutType.class),
new EnumByNameType<ItemLocation>(ItemLocation.class),
new EnumByNameType<InventoryPaperdoll>(InventoryPaperdoll.class),
new EnumByNameType<ChatMessageType>(ChatMessageType.class));
} }
} }

View File

@@ -1,85 +0,0 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
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.
*
* <h1>Internal specification</h1> <h2>The
* {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Query
* Query} object</h2>
*
* 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.
*
* <h2>The
* {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Mapper
* Mapper} object</h2>
*
* 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 <a href="http://www.rogiel.com">Rogiel</a>
*/
@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);
}
}

View File

@@ -1,51 +0,0 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}

View File

@@ -16,10 +16,6 @@
*/ */
package com.l2jserver.service.database.jdbc; 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 java.util.List;
import com.google.inject.Inject; import com.google.inject.Inject;
@@ -27,407 +23,178 @@ import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterDAO; import com.l2jserver.model.dao.CharacterDAO;
import com.l2jserver.model.id.AccountID; import com.l2jserver.model.id.AccountID;
import com.l2jserver.model.id.object.CharacterID; 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.Clan;
import com.l2jserver.model.world.L2Character; 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.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 * {@link CharacterDAO} implementation for JDBC
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public class JDBCCharacterDAO extends public class JDBCCharacterDAO extends AbstractJDBCDAO<L2Character, CharacterID>
AbstractJDBCDAO<L2Character, CharacterID> implements CharacterDAO { implements CharacterDAO {
/** /**
* The {@link CharacterID} factory * The {@link L2Character} mapper
*/ */
private final CharacterIDProvider idFactory; private final CharacterMapper mapper;
/**
* 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";
/** /**
* @param database * @param database
* the database service * the database service
* @param idFactory * @param mapper
* the character id provider * the character mapper
* @param templateIdFactory
* the template id provider
* @param accountIdFactory
* the account id provider
* @param clanIdFactory
* the clan id provider
*/ */
@Inject @Inject
public JDBCCharacterDAO(DatabaseService database, public JDBCCharacterDAO(DatabaseService database, CharacterMapper mapper) {
final CharacterIDProvider idFactory,
CharacterTemplateIDProvider templateIdFactory,
AccountIDProvider accountIdFactory, ClanIDProvider clanIdFactory) {
super(database); super(database);
this.idFactory = idFactory; this.mapper = mapper;
this.templateIdFactory = templateIdFactory;
this.accountIdFactory = accountIdFactory;
this.clanIdFactory = clanIdFactory;
} }
/**
* The mapper for {@link CharacterID}
*/
private final Mapper<CharacterID> idMapper = new Mapper<CharacterID>() {
@Override
public CharacterID map(ResultSet rs) throws SQLException {
return idFactory.resolveID(rs.getInt(CHAR_ID));
}
};
/**
* The {@link Mapper} for {@link L2Character}
*/
private final Mapper<L2Character> mapper = new CachedMapper<L2Character, CharacterID>(
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 @Override
public L2Character select(final CharacterID id) { public L2Character select(final CharacterID id) {
return database.query(new SelectSingleQuery<L2Character>() { return database.query(new SelectSingleQuery<L2Character, QCharacter>(
QCharacter.character, mapper) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q, QCharacter e) {
return "SELECT * FROM `" + TABLE + "` WHERE `" + CHAR_ID q.where(e.characterId.eq(id.getID()));
+ "` = ?";
}
@Override
protected void parametize(PreparedStatement st) throws SQLException {
st.setInt(1, id.getID());
}
@Override
protected Mapper<L2Character> mapper() {
return mapper;
} }
}); });
} }
@Override @Override
public void load(final Clan clan) { public void load(final Clan clan) {
clan.getMembers().load( clan.getMembers().load(database.query(new SelectListQuery<CharacterID, QCharacter>(
database.query(new SelectListQuery<CharacterID>() { QCharacter.character, mapper.getIDMapper()) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q, QCharacter e) {
return "SELECT `" + CHAR_ID + "` FROM `" + TABLE q.where(e.clanId.eq(clan.getID().getID()));
+ "` WHERE `" + CLAN_ID + "` = ?"; }
} }));
@Override
protected void parametize(PreparedStatement st)
throws SQLException {
st.setInt(1, clan.getID().getID());
}
@Override
protected Mapper<CharacterID> mapper() {
return idMapper;
}
}));
} }
@Override @Override
public L2Character selectByName(final String name) { public L2Character selectByName(final String name) {
return database.query(new SelectSingleQuery<L2Character>() { return database.query(new SelectSingleQuery<L2Character, QCharacter>(
QCharacter.character, mapper) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q, QCharacter e) {
return "SELECT * FROM `" + TABLE + "` WHERE `" + NAME + "` = ?"; q.where(e.name.eq(name));
}
@Override
protected void parametize(PreparedStatement st) throws SQLException {
st.setString(1, name);
}
@Override
protected Mapper<L2Character> mapper() {
return mapper;
} }
}); });
} }
@Override @Override
public List<L2Character> selectByAccount(final AccountID account) { public List<L2Character> selectByAccount(final AccountID account) {
return database.query(new SelectListQuery<L2Character>() { return database.query(new SelectListQuery<L2Character, QCharacter>(
QCharacter.character, mapper) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q, QCharacter e) {
return "SELECT * FROM `" + TABLE + "` WHERE `" + ACCOUNT_ID q.where(e.accountId.eq(account.getID()));
+ "` = ?";
}
@Override
protected void parametize(PreparedStatement st) throws SQLException {
st.setString(1, account.getID());
}
@Override
protected Mapper<L2Character> mapper() {
return mapper;
} }
}); });
} }
@Override @Override
public List<CharacterID> selectIDs() { public List<CharacterID> selectIDs() {
return database.query(new SelectListQuery<CharacterID>() { return database.query(new SelectListQuery<CharacterID, QCharacter>(
QCharacter.character, mapper.getIDMapper()) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q, QCharacter e) {
return "SELECT `" + CHAR_ID + "` FROM `" + TABLE + "`";
}
@Override
protected Mapper<CharacterID> mapper() {
return idMapper;
} }
}); });
} }
@Override @Override
public int insertObjects(L2Character... characters) { public int insertObjects(L2Character... characters) {
return database.query(new InsertUpdateQuery<L2Character>(characters) { return database.query(new InsertQuery<L2Character, QCharacter, Object>(
QCharacter.character, characters) {
@Override @Override
protected String query() { protected void map(SQLInsertClause q, L2Character o) {
return "INSERT INTO `" + TABLE + "` (`" + CHAR_ID + "`,`" q.set(e.characterId, o.getID().getID())
+ ACCOUNT_ID + "`,`" + CLAN_ID + "`,`" + NAME + "`,`" .set(e.accountId, o.getAccountID().getID())
+ RACE + "`,`" + CLASS + "`,`" + SEX + "`,`" + LEVEL .set(e.clanId,
+ "`,`" + EXPERIENCE + "`,`" + SP + "`,`" + HP + "`,`" (o.getClanID() != null ? o.getClanID().getID()
+ MP + "`,`" + CP + "`,`" + POINT_X + "`,`" + POINT_Y : null))
+ "`,`" + POINT_Z + "`,`" + POINT_ANGLE + "`,`" .set(e.name, o.getName())
+ APPEARANCE_HAIR_STYLE + "`,`" + APPEARANCE_HAIR_COLOR .set(e.race, o.getRace())
+ "`,`" + APPEARANCE_FACE .set(e.characterClass, o.getCharacterClass())
+ "`) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; .set(e.sex, o.getSex())
} .set(e.level, o.getLevel())
.set(e.experience, o.getExperience())
@Override .set(e.sp, o.getSP())
protected void parametize(PreparedStatement st, .set(e.hp, o.getHP())
L2Character character) throws SQLException { .set(e.mp, o.getMP())
final CharacterAppearance appearance = character .set(e.cp, o.getCP())
.getAppearance(); .set(e.pointX, o.getPoint().getX())
int i = 1; .set(e.pointY, o.getPoint().getY())
.set(e.pointZ, o.getPoint().getZ())
st.setInt(i++, character.getID().getID()); .set(e.pointAngle, o.getPoint().getAngle())
st.setString(i++, character.getAccountID().getID()); .set(e.appearanceHairStyle,
if (character.getClanID() != null) o.getAppearance().getHairStyle())
st.setInt(i++, character.getClanID().getID()); .set(e.appearanceHairColor,
else o.getAppearance().getHairColor())
st.setNull(i++, Types.INTEGER); .set(e.apperanceFace, o.getAppearance().getFace());
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());
} }
}); });
} }
@Override @Override
public int updateObjects(L2Character... characters) { public int updateObjects(L2Character... characters) {
return database.query(new InsertUpdateQuery<L2Character>(characters) { return database.query(new UpdateQuery<L2Character, QCharacter>(
QCharacter.character, characters) {
@Override @Override
protected String query() { protected void query(SQLUpdateClause q, L2Character o) {
return "UPDATE `" + TABLE + "` SET `" + ACCOUNT_ID + "` = ?,`" q.where(e.characterId.eq(o.getID().getID()));
+ 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 + "` = ?";
} }
@Override @Override
protected void parametize(PreparedStatement st, protected void map(SQLUpdateClause q, L2Character o) {
L2Character character) throws SQLException { q.set(e.accountId, o.getAccountID().getID())
final CharacterAppearance appearance = character .set(e.clanId,
.getAppearance(); (o.getClanID() != null ? o.getClanID().getID()
int i = 1; : null))
.set(e.name, o.getName())
// SET .set(e.race, o.getRace())
st.setString(i++, character.getAccountID().getID()); .set(e.characterClass, o.getCharacterClass())
if (character.getClanID() != null) .set(e.sex, o.getSex())
st.setInt(i++, character.getClanID().getID()); .set(e.level, o.getLevel())
else .set(e.experience, o.getExperience())
st.setNull(i++, Types.INTEGER); .set(e.sp, o.getSP())
.set(e.hp, o.getHP())
st.setString(i++, character.getName()); .set(e.mp, o.getMP())
.set(e.cp, o.getCP())
st.setString(i++, character.getRace().name()); .set(e.pointX, o.getPoint().getX())
st.setString(i++, character.getCharacterClass().name()); .set(e.pointY, o.getPoint().getY())
st.setString(i++, character.getSex().name()); .set(e.pointZ, o.getPoint().getZ())
.set(e.pointAngle, o.getPoint().getAngle())
st.setInt(i++, character.getLevel()); .set(e.appearanceHairStyle,
st.setLong(i++, character.getExperience()); o.getAppearance().getHairStyle())
st.setInt(i++, character.getSP()); .set(e.appearanceHairColor,
o.getAppearance().getHairColor())
st.setDouble(i++, character.getHP()); .set(e.apperanceFace, o.getAppearance().getFace());
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());
} }
}); });
} }
@Override @Override
public int deleteObjects(L2Character... characters) { public int deleteObjects(L2Character... characters) {
return database.query(new InsertUpdateQuery<L2Character>(characters) { return database.query(new DeleteQuery<L2Character, QCharacter>(
QCharacter.character, characters) {
@Override @Override
protected String query() { protected void query(SQLDeleteClause q, L2Character o) {
return "DELETE FROM `" + TABLE + "` WHERE `" + CHAR_ID q.where(e.characterId.eq(o.getID().getID()));
+ "` = ?";
}
@Override
protected void parametize(PreparedStatement st,
L2Character character) throws SQLException {
st.setInt(1, character.getID().getID());
} }
}); });
} }

View File

@@ -16,9 +16,6 @@
*/ */
package com.l2jserver.service.database.jdbc; package com.l2jserver.service.database.jdbc;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List; import java.util.List;
import com.google.inject.Inject; import com.google.inject.Inject;
@@ -26,17 +23,18 @@ import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterFriendDAO; import com.l2jserver.model.dao.CharacterFriendDAO;
import com.l2jserver.model.game.CharacterFriend; import com.l2jserver.model.game.CharacterFriend;
import com.l2jserver.model.id.FriendID; 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.L2Character;
import com.l2jserver.model.world.character.CharacterFriendList; 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.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 * {@link CharacterFriendDAO} implementation for JDBC
@@ -47,107 +45,47 @@ public class JDBCCharacterFriendDAO extends
AbstractJDBCDAO<CharacterFriend, FriendID> implements AbstractJDBCDAO<CharacterFriend, FriendID> implements
CharacterFriendDAO { CharacterFriendDAO {
/** /**
* The {@link FriendID} provider * The {@link CharacterFriend} mapper
*/ */
private final FriendIDProvider idProvider; private final CharacterFriendMapper mapper;
/**
* 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";
/** /**
* @param database * @param database
* the database service * the database service
* @param idProvider * @param mapper
* the frind id provider * the character friend mapper
* @param charIdProvider
* the character id provider
*/ */
@Inject @Inject
public JDBCCharacterFriendDAO(DatabaseService database, public JDBCCharacterFriendDAO(DatabaseService database,
final FriendIDProvider idProvider, CharacterFriendMapper mapper) {
CharacterIDProvider charIdProvider) {
super(database); super(database);
this.idProvider = idProvider; this.mapper = mapper;
this.charIdProvider = charIdProvider;
} }
/**
* The {@link Mapper} for {@link FriendID}
*/
private final Mapper<FriendID> idMapper = new Mapper<FriendID>() {
@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<CharacterFriend> mapper = new CachedMapper<CharacterFriend, FriendID>(
database, idMapper) {
@Override
protected CharacterFriend map(FriendID id, ResultSet rs)
throws SQLException {
return new CharacterFriend(id);
}
};
@Override @Override
public CharacterFriend select(final FriendID id) { public CharacterFriend select(final FriendID id) {
return database.query(new SelectSingleQuery<CharacterFriend>() { return database
@Override .query(new SelectSingleQuery<CharacterFriend, QCharacterFriend>(
protected String query() { QCharacterFriend.characterFriend, mapper) {
return "SELECT * FROM `" + TABLE + "` WHERE `" + CHAR_ID @Override
+ "` = ? AND `" + CHAR_ID_FRIEND + "` = ?"; protected void query(AbstractSQLQuery<?> q,
} QCharacterFriend e) {
q.where(e.characterId.eq(id.getCharacterID().getID())
@Override .and(e.characterIdFriend.eq(id.getFriendID()
protected void parametize(PreparedStatement st) throws SQLException { .getID())));
st.setInt(1, id.getID1().getID()); }
st.setInt(2, id.getID2().getID()); });
}
@Override
protected Mapper<CharacterFriend> mapper() {
return mapper;
}
});
} }
@Override @Override
public void load(final L2Character character) { public void load(final L2Character character) {
final List<CharacterFriend> list = database final List<CharacterFriend> list = database
.query(new SelectListQuery<CharacterFriend>() { .query(new SelectListQuery<CharacterFriend, QCharacterFriend>(
QCharacterFriend.characterFriend, mapper) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q,
return "SELECT * FROM `" + TABLE + "` WHERE `" QCharacterFriend e) {
+ CHAR_ID + "` = ?"; q.where(e.characterId.eq(character.getID().getID()));
}
@Override
protected void parametize(PreparedStatement st)
throws SQLException {
st.setInt(1, character.getID().getID());
}
@Override
protected Mapper<CharacterFriend> mapper() {
return mapper;
} }
}); });
character.getFriendList().load(list); character.getFriendList().load(list);
@@ -155,35 +93,25 @@ public class JDBCCharacterFriendDAO extends
@Override @Override
public List<FriendID> selectIDs() { public List<FriendID> selectIDs() {
return database.query(new SelectListQuery<FriendID>() { return database.query(new SelectListQuery<FriendID, QCharacterFriend>(
QCharacterFriend.characterFriend, mapper.getIDMapper()) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q, QCharacterFriend e) {
return "SELECT * FROM `" + TABLE + "`";
}
@Override
protected Mapper<FriendID> mapper() {
return idMapper;
} }
}); });
} }
@Override @Override
public int insertObjects(CharacterFriend... friends) { public int insertObjects(CharacterFriend... friends) {
return database.query(new InsertUpdateQuery<CharacterFriend>(friends) { return database
@Override .query(new InsertQuery<CharacterFriend, QCharacterFriend, Object>(
protected String query() { QCharacterFriend.characterFriend, friends) {
return "INSERT INTO `" + TABLE + "` (`" + CHAR_ID + "`,`" @Override
+ CHAR_ID_FRIEND + "`) VALUES(?,?)"; protected void map(SQLInsertClause q, CharacterFriend o) {
} q.set(e.characterId, o.getCharacterID().getID()).set(
e.characterIdFriend, o.getFriendID().getID());
@Override }
protected void parametize(PreparedStatement st, });
CharacterFriend friend) throws SQLException {
st.setInt(1, friend.getCharacterID().getID());
st.setInt(2, friend.getFriendID().getID());
}
});
} }
@Override @Override
@@ -195,20 +123,17 @@ public class JDBCCharacterFriendDAO extends
@Override @Override
public int deleteObjects(CharacterFriend... friends) { public int deleteObjects(CharacterFriend... friends) {
return database.query(new InsertUpdateQuery<CharacterFriend>(friends) { return database
@Override .query(new DeleteQuery<CharacterFriend, QCharacterFriend>(
protected String query() { QCharacterFriend.characterFriend, friends) {
return "DELETE FROM `" + TABLE + "` WHERE `" + CHAR_ID @Override
+ "` = ?,`" + CHAR_ID_FRIEND + "` = ?"; protected void query(SQLDeleteClause q, CharacterFriend o) {
} q.where(e.characterId.eq(
o.getID().getCharacterID().getID()).and(
@Override e.characterIdFriend.eq(o.getID().getFriendID()
protected void parametize(PreparedStatement st, .getID())));
CharacterFriend friend) throws SQLException { }
st.setInt(1, friend.getCharacterID().getID()); });
st.setInt(2, friend.getFriendID().getID());
}
});
} }
@Override @Override
@@ -228,7 +153,7 @@ public class JDBCCharacterFriendDAO extends
} }
return true; return true;
} }
@Override @Override
protected CharacterFriend[] wrap(Model<?>... objects) { protected CharacterFriend[] wrap(Model<?>... objects) {
final CharacterFriend[] array = new CharacterFriend[objects.length]; final CharacterFriend[] array = new CharacterFriend[objects.length];

View File

@@ -16,32 +16,27 @@
*/ */
package com.l2jserver.service.database.jdbc; package com.l2jserver.service.database.jdbc;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List; import java.util.List;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.l2jserver.model.Model; import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterFriendDAO; import com.l2jserver.model.dao.CharacterFriendDAO;
import com.l2jserver.model.dao.CharacterShortcutDAO; import com.l2jserver.model.dao.CharacterShortcutDAO;
import com.l2jserver.model.game.CharacterFriend;
import com.l2jserver.model.game.CharacterShortcut; import com.l2jserver.model.game.CharacterShortcut;
import com.l2jserver.model.game.CharacterShortcut.ShortcutType;
import com.l2jserver.model.id.CharacterShortcutID; 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.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.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 * {@link CharacterFriendDAO} implementation for JDBC
@@ -51,239 +46,114 @@ import com.l2jserver.service.database.DatabaseService;
public class JDBCCharacterShortcutDAO extends public class JDBCCharacterShortcutDAO extends
AbstractJDBCDAO<CharacterShortcut, CharacterShortcutID> implements AbstractJDBCDAO<CharacterShortcut, CharacterShortcutID> implements
CharacterShortcutDAO { CharacterShortcutDAO {
/** private final CharacterShortcutMapper mapper;
* 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";
/** /**
* @param database * @param database
* the database service * the database service
* @param idProvider * @param mapper
* the frind id provider * the {@link CharacterShortcut} mapper
* @param charIdProvider
* the character id provider
* @param itemIdProvider
* the item id provider
*/ */
@Inject @Inject
public JDBCCharacterShortcutDAO(DatabaseService database, public JDBCCharacterShortcutDAO(DatabaseService database,
final CharacterShortcutIDProvider idProvider, CharacterShortcutMapper mapper) {
CharacterIDProvider charIdProvider, ItemIDProvider itemIdProvider) {
super(database); super(database);
this.idProvider = idProvider; this.mapper = mapper;
this.charIdProvider = charIdProvider;
this.itemIdProvider = itemIdProvider;
} }
/**
* The {@link Mapper} for {@link FriendID}
*/
private final Mapper<CharacterShortcutID> idMapper = new Mapper<CharacterShortcutID>() {
@Override
public CharacterShortcutID map(ResultSet rs) throws SQLException {
return idProvider.resolveID(rs.getInt(SHORTCUT_ID));
}
};
/**
* The {@link Mapper} for {@link CharacterFriend}
*/
private final Mapper<CharacterShortcut> mapper = new CachedMapper<CharacterShortcut, CharacterShortcutID>(
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 @Override
public CharacterShortcut select(final CharacterShortcutID id) { public CharacterShortcut select(final CharacterShortcutID id) {
return database.query(new SelectSingleQuery<CharacterShortcut>() { return database
@Override .query(new SelectSingleQuery<CharacterShortcut, QCharacterShortcut>(
protected String query() { QCharacterShortcut.characterShortcut, mapper) {
return "SELECT * FROM `" + TABLE + "` WHERE `" + SHORTCUT_ID @Override
+ "` = ?"; protected void query(AbstractSQLQuery<?> q,
} QCharacterShortcut e) {
q.where(e.shortcutId.eq(id.getID()));
@Override }
protected void parametize(PreparedStatement st) throws SQLException { });
st.setInt(1, id.getID());
}
@Override
protected Mapper<CharacterShortcut> mapper() {
return mapper;
}
});
} }
@Override @Override
public List<CharacterShortcut> selectByCharacter(final L2Character character) { public List<CharacterShortcut> selectByCharacter(final L2Character character) {
return database.query(new SelectListQuery<CharacterShortcut>() { return database
@Override .query(new SelectListQuery<CharacterShortcut, QCharacterShortcut>(
protected String query() { QCharacterShortcut.characterShortcut, mapper) {
return "SELECT * FROM `" + TABLE + "` WHERE `" + CHAR_ID @Override
+ "` = ?"; protected void query(AbstractSQLQuery<?> q,
} QCharacterShortcut e) {
q.where(e.characterId.eq(character.getID().getID()));
@Override }
protected void parametize(PreparedStatement st) throws SQLException { });
st.setInt(1, character.getID().getID());
}
@Override
protected Mapper<CharacterShortcut> mapper() {
return mapper;
}
});
} }
@Override @Override
public List<CharacterShortcutID> selectIDs() { public List<CharacterShortcutID> selectIDs() {
return database.query(new SelectListQuery<CharacterShortcutID>() { return database
@Override .query(new SelectListQuery<CharacterShortcutID, QCharacterShortcut>(
protected String query() { QCharacterShortcut.characterShortcut, mapper
return "SELECT * FROM `" + TABLE + "`"; .getIDMapper()) {
} @Override
protected void query(AbstractSQLQuery<?> q,
@Override QCharacterShortcut e) {
protected Mapper<CharacterShortcutID> mapper() { }
return idMapper; });
}
});
} }
@Override @Override
public int insertObjects(CharacterShortcut... shortcuts) { public int insertObjects(CharacterShortcut... shortcuts) {
return database.query(new InsertUpdateQuery<CharacterShortcut>( return database
shortcuts) { .query(new InsertQuery<CharacterShortcut, QCharacterShortcut, Integer>(
@Override QCharacterShortcut.characterShortcut,
protected String query() { QCharacterShortcut.characterShortcut.shortcutId,
return "INSERT INTO `" + TABLE + "` (`" + CHAR_ID + "`,`" shortcuts) {
+ TYPE + "`, `" + OBJECT_ID + "`, `" + SLOT + "`, `"
+ PAGE + "`) VALUES(?,?,?,?,?)";
}
@Override
protected void parametize(PreparedStatement st,
CharacterShortcut shortcut) throws SQLException {
int i = 1;
st.setInt(i++, shortcut.getCharacterID().getID());
st.setString(i++, shortcut.getType().name());
switch (shortcut.getType()) {
case ITEM:
st.setInt(i++, shortcut.getItemID().getID());
break;
}
st.setInt(i++, shortcut.getSlot());
st.setInt(i++, shortcut.getPage());
}
@Override
protected Mapper<CharacterShortcutID> keyMapper() {
return new Mapper<CharacterShortcutID>() {
@Override @Override
public CharacterShortcutID map(ResultSet rs) protected void map(SQLInsertClause q, CharacterShortcut o) {
throws SQLException { q.set(e.characterId, o.getID().getID())
return idProvider.resolveID(rs.getInt(1)); .set(e.type, o.getType())
}; .set(e.objectId, o.getItemID().getID())
}; .set(e.slot, o.getSlot())
} .set(e.page, o.getPage());
}); }
@Override
protected void key(Integer k, CharacterShortcut o) {
// TODO
}
});
} }
@Override @Override
public int updateObjects(CharacterShortcut... shortcuts) { public int updateObjects(CharacterShortcut... shortcuts) {
return database.query(new InsertUpdateQuery<CharacterShortcut>( return database
shortcuts) { .query(new UpdateQuery<CharacterShortcut, QCharacterShortcut>(
@Override QCharacterShortcut.characterShortcut, shortcuts) {
protected String query() { @Override
return "UPDATE `" + TABLE + "` SET `" + CHAR_ID + "` = ?,`" protected void query(SQLUpdateClause q, CharacterShortcut o) {
+ TYPE + "` = ?, `" + OBJECT_ID + "` = ?, `" + SLOT q.where(e.shortcutId.eq(o.getID().getID()));
+ "` = ?, `" + PAGE + "` = ? WHERE `" + SHORTCUT_ID }
+ "` = ?";
}
@Override @Override
protected void parametize(PreparedStatement st, protected void map(SQLUpdateClause q, CharacterShortcut o) {
CharacterShortcut shortcut) throws SQLException { q.set(e.characterId, o.getID().getID())
int i = 1; .set(e.type, o.getType())
st.setInt(i++, shortcut.getCharacterID().getID()); .set(e.objectId, o.getItemID().getID())
st.setString(i++, shortcut.getType().name()); .set(e.slot, o.getSlot())
switch (shortcut.getType()) { .set(e.page, o.getPage());
case ITEM: }
st.setInt(i++, shortcut.getItemID().getID()); });
break;
}
st.setInt(i++, shortcut.getSlot());
st.setInt(i++, shortcut.getPage());
st.setInt(i++, shortcut.getID().getID());
}
});
} }
@Override @Override
public int deleteObjects(CharacterShortcut... shortcuts) { public int deleteObjects(CharacterShortcut... shortcuts) {
return database.query(new InsertUpdateQuery<CharacterShortcut>( return database
shortcuts) { .query(new DeleteQuery<CharacterShortcut, QCharacterShortcut>(
@Override QCharacterShortcut.characterShortcut, shortcuts) {
protected String query() { @Override
return "DELETE FROM `" + TABLE + "` WHERE `" + SHORTCUT_ID protected void query(SQLDeleteClause q, CharacterShortcut o) {
+ "` = ?"; q.where(e.shortcutId.eq(o.getID().getID()));
} }
});
@Override
protected void parametize(PreparedStatement st,
CharacterShortcut shortcut) throws SQLException {
st.setInt(1, shortcut.getID().getID());
}
});
} }
@Override @Override

View File

@@ -16,29 +16,26 @@
*/ */
package com.l2jserver.service.database.jdbc; package com.l2jserver.service.database.jdbc;
import java.sql.PreparedStatement; import java.util.Collection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.l2jserver.model.Model; import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterDAO; import com.l2jserver.model.dao.CharacterDAO;
import com.l2jserver.model.dao.ChatMessageDAO; import com.l2jserver.model.dao.ChatMessageDAO;
import com.l2jserver.model.id.ChatMessageID; import com.l2jserver.model.id.ChatMessageID;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.id.object.provider.CharacterIDProvider;
import com.l2jserver.model.id.provider.ChatMessageIDProvider;
import com.l2jserver.model.server.ChatMessage; import com.l2jserver.model.server.ChatMessage;
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.DatabaseService;
import com.l2jserver.service.game.chat.ChatMessageType; 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.ChatMessageMapper;
import com.l2jserver.service.database.model.QLogChat;
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 * {@link CharacterDAO} implementation for JDBC
@@ -47,186 +44,99 @@ import com.l2jserver.service.game.chat.ChatMessageType;
*/ */
public class JDBCChatMessageDAO extends public class JDBCChatMessageDAO extends
AbstractJDBCDAO<ChatMessage, ChatMessageID> implements ChatMessageDAO { AbstractJDBCDAO<ChatMessage, ChatMessageID> implements ChatMessageDAO {
/** private final ChatMessageMapper mapper;
* The {@link ChatMessageID} factory
*/
private final ChatMessageIDProvider idFactory;
/**
* The {@link CharacterID} factory
*/
private final CharacterIDProvider charIdFactory;
/**
* Character table name
*/
public static final String TABLE = "log_chat";
// FIELDS
public static final String MESSAGE_ID = "message_id";
public static final String TYPE = "type";
public static final String CHANNEL_ID = "channel_id";
public static final String SENDER = "sender";
public static final String DATE = "date";
public static final String MESSAGE = "message";
/** /**
* @param database * @param database
* the database service * the database service
* @param idFactory * @param mapper
* the chat message id provider * the mapper
* @param charIdFactory
* the character id provider
*/ */
@Inject @Inject
public JDBCChatMessageDAO(DatabaseService database, public JDBCChatMessageDAO(DatabaseService database, ChatMessageMapper mapper) {
ChatMessageIDProvider idFactory,
final CharacterIDProvider charIdFactory) {
super(database); super(database);
this.idFactory = idFactory; this.mapper = mapper;
this.charIdFactory = charIdFactory;
} }
/**
* The {@link Mapper} for {@link ChatMessageID}
*/
private final Mapper<ChatMessageID> idMapper = new Mapper<ChatMessageID>() {
@Override
public ChatMessageID map(ResultSet rs) throws SQLException {
return idFactory.resolveID(rs.getInt(MESSAGE_ID));
}
};
/**
* The {@link Mapper} for {@link ChatMessageID} as a PRIMARY KEY
*/
private final Mapper<ChatMessageID> primaryKeyMapper = new Mapper<ChatMessageID>() {
@Override
public ChatMessageID map(ResultSet rs) throws SQLException {
return idFactory.resolveID(rs.getInt(1));
}
};
/**
* The {@link Mapper} for {@link ChatMessage}
*/
private final Mapper<ChatMessage> mapper = new CachedMapper<ChatMessage, ChatMessageID>(
database, idMapper) {
@Override
protected ChatMessage map(ChatMessageID id, ResultSet rs)
throws SQLException {
final ChatMessage message = new ChatMessage();
message.setID(id);
message.setType(ChatMessageType.valueOf(rs.getString(TYPE)));
switch (message.getType()) {
case SHOUT:
message.setTarget(charIdFactory.resolveID(rs.getInt(CHANNEL_ID)));
break;
default:
message.setChannelID(rs.getInt(CHANNEL_ID));
break;
}
message.setSender(charIdFactory.resolveID(rs.getInt(SENDER)));
message.setDate(new Date(rs.getTimestamp(DATE).getTime()));
message.setMessage(rs.getString(MESSAGE));
return message;
}
};
@Override @Override
public ChatMessage select(final ChatMessageID id) { public ChatMessage select(final ChatMessageID id) {
return database.query(new SelectSingleQuery<ChatMessage>() { return database.query(new SelectSingleQuery<ChatMessage, QLogChat>(
QLogChat.logChat, mapper) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q, QLogChat e) {
return "SELECT * FROM `" + TABLE + "` WHERE `" + MESSAGE_ID q.where(e.messageId.eq(id.getID()));
+ "` = ?";
}
@Override
protected void parametize(PreparedStatement st) throws SQLException {
st.setInt(1, id.getID());
}
@Override
protected Mapper<ChatMessage> mapper() {
return mapper;
} }
}); });
} }
@Override @Override
public List<ChatMessageID> selectIDs() { public Collection<ChatMessageID> selectIDs() {
return database.query(new SelectListQuery<ChatMessageID>() { return database.query(new SelectListQuery<ChatMessageID, QLogChat>(
QLogChat.logChat, mapper.getIDMapper()) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q, QLogChat e) {
return "SELECT * FROM `" + TABLE + "`";
}
@Override
protected Mapper<ChatMessageID> mapper() {
return idMapper;
} }
}); });
} }
@Override @Override
public int insertObjects(ChatMessage... messages) { public int insertObjects(ChatMessage... objects) {
return database.query(new InsertUpdateQuery<ChatMessage>(messages) { return database.query(new InsertQuery<ChatMessage, QLogChat, Integer>(
QLogChat.logChat, QLogChat.logChat.messageId, objects) {
@Override @Override
protected String query() { protected void map(SQLInsertClause q, ChatMessage o) {
return "INSERT INTO `" + TABLE + "` (`" + TYPE + "`,`" q.set(e.type, o.getType()).set(e.sender, o.getSender().getID())
+ CHANNEL_ID + "`,`" + SENDER + "`,`" + DATE + "`,`" .set(e.date, o.getDate())
+ MESSAGE + "`) VALUES(?,?,?,?,?)"; .set(e.message, o.getMessage());
} switch (o.getType()) {
@Override
protected void parametize(PreparedStatement st, ChatMessage message)
throws SQLException {
int i = 1;
st.setString(i++, message.getType().name());
switch (message.getType()) {
case SHOUT: case SHOUT:
st.setInt(i++, message.getTarget().getID()); q.set(e.channelId, o.getTarget().getID());
break; break;
default: default:
st.setInt(i++, message.getChannelID()); q.set(e.channelId, o.getChannelID());
break; break;
} }
st.setInt(i++, message.getSender().getID());
st.setTimestamp(i++, new Timestamp(message.getDate().getTime()));
st.setString(i++, message.getMessage());
}
@Override
protected Mapper<ChatMessageID> keyMapper() {
return primaryKeyMapper;
} }
}); });
} }
@Override @Override
public int updateObjects(ChatMessage... messages) { public int updateObjects(ChatMessage... objects) {
// cannot update chat message logs return database.query(new UpdateQuery<ChatMessage, QLogChat>(
return 0; QLogChat.logChat, objects) {
}
@Override
public int deleteObjects(ChatMessage... messages) {
return database.query(new InsertUpdateQuery<ChatMessage>(messages) {
@Override @Override
protected String query() { protected void query(SQLUpdateClause q, ChatMessage o) {
return "DELETE FROM `" + TABLE + "` WHERE `" + MESSAGE_ID q.where(e.messageId.eq(o.getID().getID()));
+ "` = ?";
} }
@Override @Override
protected void parametize(PreparedStatement st, ChatMessage message) protected void map(SQLUpdateClause q, ChatMessage o) {
throws SQLException { q.set(e.type, o.getType()).set(e.sender, o.getSender().getID())
st.setInt(1, message.getID().getID()); .set(e.date, o.getDate())
.set(e.message, o.getMessage());
switch (o.getType()) {
case SHOUT:
q.set(e.channelId, o.getTarget().getID());
break;
default:
q.set(e.channelId, o.getChannelID());
break;
}
} }
}); });
} }
@Override
public int deleteObjects(ChatMessage... objects) {
return database.query(new DeleteQuery<ChatMessage, QLogChat>(
QLogChat.logChat, objects) {
@Override
protected void query(SQLDeleteClause q, ChatMessage o) {
q.where(e.messageId.eq(o.getID().getID()));
}
});
}
@Override @Override
protected ChatMessage[] wrap(Model<?>... objects) { protected ChatMessage[] wrap(Model<?>... objects) {
final ChatMessage[] array = new ChatMessage[objects.length]; final ChatMessage[] array = new ChatMessage[objects.length];

View File

@@ -16,167 +16,109 @@
*/ */
package com.l2jserver.service.database.jdbc; package com.l2jserver.service.database.jdbc;
import java.sql.PreparedStatement; import java.util.Collection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.l2jserver.model.Model; import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterDAO; import com.l2jserver.model.dao.CharacterDAO;
import com.l2jserver.model.dao.ClanDAO; import com.l2jserver.model.dao.ClanDAO;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.id.object.ClanID; import com.l2jserver.model.id.object.ClanID;
import com.l2jserver.model.id.object.provider.CharacterIDProvider;
import com.l2jserver.model.id.object.provider.ClanIDProvider;
import com.l2jserver.model.world.Clan; import com.l2jserver.model.world.Clan;
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.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.ClanMapper;
import com.l2jserver.service.database.model.QClan;
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 * {@link CharacterDAO} implementation for JDBC
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public class JDBCClanDAO extends AbstractJDBCDAO<Clan, ClanID> public class JDBCClanDAO extends AbstractJDBCDAO<Clan, ClanID> implements
implements ClanDAO { ClanDAO {
/** private final ClanMapper mapper;
* The {@link ClanID} factory
*/
private final ClanIDProvider idFactory;
/**
* The {@link CharacterID} factory
*/
@SuppressWarnings("unused")
private final CharacterIDProvider charIdFactory;
/**
* Character table name
*/
public static final String TABLE = "clan";
// FIELDS
public static final String CLAN_ID = "clan_id";
public static final String CHAR_ID_LEADER = "character_id_leader";
/** /**
* @param database * @param database
* the database service * the database service
* @param clanIdFactory * @param mapper
* the clan id provider * the mapper
* @param idFactory
* the character id provider
*/ */
@Inject @Inject
public JDBCClanDAO(DatabaseService database, ClanIDProvider clanIdFactory, public JDBCClanDAO(DatabaseService database, final ClanMapper mapper) {
final CharacterIDProvider idFactory) {
super(database); super(database);
this.idFactory = clanIdFactory; this.mapper = mapper;
this.charIdFactory = idFactory;
} }
/**
* The {@link Mapper} for {@link ClanID}
*/
private final Mapper<ClanID> idMapper = new Mapper<ClanID>() {
@Override
public ClanID map(ResultSet rs) throws SQLException {
return idFactory.resolveID(rs.getInt(CLAN_ID));
}
};
/**
* The {@link Mapper} for {@link Clan}
*/
private final Mapper<Clan> mapper = new CachedMapper<Clan, ClanID>(
database, idMapper) {
@Override
protected Clan map(ClanID id, ResultSet rs) throws SQLException {
final Clan clan = new Clan();
clan.setID(id);
return clan;
}
};
@Override @Override
public Clan select(final ClanID id) { public Clan select(final ClanID id) {
return database.query(new SelectSingleQuery<Clan>() { return database.query(new SelectSingleQuery<Clan, QClan>(QClan.clan,
mapper) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q, QClan e) {
return "SELECT * FROM `" + TABLE + "` WHERE `" + CLAN_ID q.where(e.clanId.eq(id.getID()));
+ "` = ?";
}
@Override
protected void parametize(PreparedStatement st) throws SQLException {
st.setInt(1, id.getID());
}
@Override
protected Mapper<Clan> mapper() {
return mapper;
} }
}); });
} }
@Override @Override
public List<ClanID> selectIDs() { public Collection<ClanID> selectIDs() {
return database.query(new SelectListQuery<ClanID>() { return database.query(new SelectListQuery<ClanID, QClan>(QClan.clan,
mapper.getIDMapper()) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q, QClan e) {
return "SELECT * FROM `" + TABLE + "`";
}
@Override
protected Mapper<ClanID> mapper() {
return idMapper;
} }
}); });
} }
@Override @Override
public int insertObjects(Clan... clans) { public int insertObjects(Clan... objects) {
return database.query(new InsertUpdateQuery<Clan>(clans) { return database.query(new InsertQuery<Clan, QClan, Integer>(QClan.clan,
QClan.clan.clanId, objects) {
@Override @Override
protected String query() { protected void map(SQLInsertClause q, Clan o) {
return "INSERT INTO `" + TABLE + "` (`" + CLAN_ID q.set(e.clanId, o.getID().getID()).set(e.characterIdLeader,
+ "`) VALUES(?)"; o.getLeaderID().getID());
}
@Override
protected void parametize(PreparedStatement st, Clan clan)
throws SQLException {
st.setInt(1, clan.getID().getID());
} }
}); });
} }
@Override @Override
public int updateObjects(Clan... clans) { public int updateObjects(Clan... objects) {
// TODO implement clan update return database
return 0; .query(new UpdateQuery<Clan, QClan>(QClan.clan, objects) {
@Override
protected void query(SQLUpdateClause q, Clan o) {
q.where(e.clanId.eq(o.getID().getID()));
}
@Override
protected void map(SQLUpdateClause q, Clan o) {
q.set(e.clanId, o.getID().getID()).set(
e.characterIdLeader, o.getLeaderID().getID());
}
});
} }
@Override @Override
public int deleteObjects(Clan... clans) { public int deleteObjects(Clan... objects) {
return database.query(new InsertUpdateQuery<Clan>(clans) { return database
@Override .query(new DeleteQuery<Clan, QClan>(QClan.clan, objects) {
protected String query() { @Override
return "DELETE FROM `" + TABLE + "` WHERE `" + CLAN_ID protected void query(SQLDeleteClause q, Clan o) {
+ "` = ?"; q.where(e.clanId.eq(o.getID().getID()));
} }
});
@Override
protected void parametize(PreparedStatement st, Clan clan)
throws SQLException {
st.setInt(1, clan.getID().getID());
}
});
} }
@Override @Override
protected Clan[] wrap(Model<?>... objects) { protected Clan[] wrap(Model<?>... objects) {
final Clan[] array = new Clan[objects.length]; final Clan[] array = new Clan[objects.length];

View File

@@ -16,331 +16,162 @@
*/ */
package com.l2jserver.service.database.jdbc; package com.l2jserver.service.database.jdbc;
import java.sql.PreparedStatement; import java.util.Collection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List; import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.l2jserver.model.Model; import com.l2jserver.model.Model;
import com.l2jserver.model.dao.ItemDAO; import com.l2jserver.model.dao.ItemDAO;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.id.object.ItemID; 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.template.ItemTemplateID;
import com.l2jserver.model.id.template.provider.ItemTemplateIDProvider;
import com.l2jserver.model.template.item.ItemTemplate;
import com.l2jserver.model.world.Item; import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character; import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
import com.l2jserver.model.world.character.CharacterInventory.ItemLocation; import com.l2jserver.model.world.character.CharacterInventory.ItemLocation;
import com.l2jserver.service.database.AbstractJDBCDatabaseService.CachedMapper;
import com.l2jserver.service.database.AbstractJDBCDatabaseService.DeleteQuery;
import com.l2jserver.service.database.AbstractJDBCDatabaseService.InsertUpdateQuery;
import com.l2jserver.service.database.AbstractJDBCDatabaseService.Mapper;
import com.l2jserver.service.database.AbstractJDBCDatabaseService.SelectListQuery;
import com.l2jserver.service.database.AbstractJDBCDatabaseService.SelectSingleQuery;
import com.l2jserver.service.database.DatabaseService; import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.util.geometry.Coordinate; 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.ItemMapper;
import com.l2jserver.service.database.model.QItem;
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 ItemDAO} implementation for JDBC * {@link ItemDAO} implementation for JDBC
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public class JDBCItemDAO extends AbstractJDBCDAO<Item, ItemID> public class JDBCItemDAO extends AbstractJDBCDAO<Item, ItemID> implements
implements ItemDAO { ItemDAO {
/** private final ItemMapper mapper;
* The logger
*/
private final Logger log = LoggerFactory.getLogger(this.getClass());
/**
* The {@link ItemID} factory
*/
private final ItemIDProvider idFactory;
/**
* The {@link ItemTemplateID} factory
*/
private final ItemTemplateIDProvider templateIdFactory;
/**
* The {@link CharacterID} factory
*/
private final CharacterIDProvider charIdFactory;
/**
* Character table name
*/
public static final String TABLE = "item";
// FIELDS
public static final String ITEM_ID = "item_id";
public static final String TEMPLATE_ID = "template_id";
public static final String CHAR_ID = JDBCCharacterDAO.CHAR_ID;
public static final String LOCATION = "location";
public static final String PAPERDOLL = "paperdoll";
public static final String COUNT = "count";
public static final String COORD_X = "coord_x";
public static final String COORD_Y = "coord_y";
public static final String COORD_Z = "coord_z";
/** /**
* @param database * @param database
* the database service * the database service
* @param idFactory * @param mapper
* the item id provider * the mapper
* @param templateIdFactory
* the item template id provider
* @param charIdFactory
* the character id provider
*/ */
@Inject @Inject
public JDBCItemDAO(DatabaseService database, public JDBCItemDAO(DatabaseService database, ItemMapper mapper) {
final ItemIDProvider idFactory,
ItemTemplateIDProvider templateIdFactory,
CharacterIDProvider charIdFactory) {
super(database); super(database);
this.idFactory = idFactory; this.mapper = mapper;
this.templateIdFactory = templateIdFactory;
this.charIdFactory = charIdFactory;
} }
/**
* The {@link Mapper} for {@link ItemID}
*/
private final Mapper<ItemID> idMapper = new Mapper<ItemID>() {
@Override
public ItemID map(ResultSet rs) throws SQLException {
return idFactory.resolveID(rs.getInt(ITEM_ID));
}
};
/**
* The {@link Mapper} instance
*/
private final Mapper<Item> mapper = new CachedMapper<Item, ItemID>(
database, idMapper) {
@Override
public Item map(ItemID id, ResultSet rs) throws SQLException {
final ItemTemplateID templateId = templateIdFactory.resolveID(rs
.getInt(TEMPLATE_ID));
final ItemTemplate template = templateId.getTemplate();
if (template == null) {
log.warn("No template found for {} while loading {}",
templateId, id);
return null;
}
final Item item = template.create();
item.setID(id);
if (rs.getObject(CHAR_ID) != null)
item.setOwnerID(charIdFactory.resolveID(rs.getInt(CHAR_ID)));
if (rs.getObject(LOCATION) != null)
item.setLocation(ItemLocation.valueOf(rs.getString(LOCATION)));
if (rs.getObject(PAPERDOLL) != null)
item.setPaperdoll(InventoryPaperdoll.valueOf(rs
.getString(PAPERDOLL)));
item.setCount(rs.getInt(COUNT));
if (rs.getObject(COORD_X) != null && rs.getObject(COORD_Y) != null
&& rs.getObject(COORD_Z) != null)
item.setPosition(Coordinate.fromXYZ(rs.getInt(COORD_X),
rs.getInt(COORD_Y), rs.getInt(COORD_Z)));
return item;
}
};
@Override @Override
public Item select(final ItemID id) { public Item select(final ItemID id) {
return database.query(new SelectSingleQuery<Item>() { return database.query(new SelectSingleQuery<Item, QItem>(QItem.item,
mapper) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q, QItem e) {
return "SELECT * FROM `" + TABLE + "` WHERE `" + ITEM_ID q.where(e.itemId.eq(id.getID()));
+ "` = ?";
}
@Override
protected void parametize(PreparedStatement st) throws SQLException {
st.setInt(1, id.getID());
}
@Override
protected Mapper<Item> mapper() {
return mapper;
} }
}); });
} }
@Override @Override
public List<Item> selectByCharacter(final L2Character character) { public List<Item> selectByCharacter(final L2Character character) {
return database.query(new SelectListQuery<Item>() { return database.query(new SelectListQuery<Item, QItem>(QItem.item,
mapper) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q, QItem e) {
return "SELECT * FROM `" + TABLE + "` WHERE `" + CHAR_ID q.where(e.characterId.eq(character.getID().getID()));
+ "` = ? AND `location` = ?";
}
@Override
protected void parametize(PreparedStatement st) throws SQLException {
st.setInt(1, character.getID().getID());
st.setString(2, ItemLocation.INVENTORY.name());
}
@Override
protected Mapper<Item> mapper() {
return mapper;
} }
}); });
} }
@Override @Override
public List<Item> selectDroppedItems() { public List<Item> selectDroppedItems() {
return database.query(new SelectListQuery<Item>() { return database.query(new SelectListQuery<Item, QItem>(QItem.item,
mapper) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q, QItem e) {
return "SELECT * FROM `" + TABLE + "` WHERE `" + LOCATION q.where(e.location.eq(ItemLocation.GROUND));
+ "` = ?";
}
@Override
protected void parametize(PreparedStatement st) throws SQLException {
st.setString(1, ItemLocation.GROUND.name());
}
@Override
protected Mapper<Item> mapper() {
return mapper;
} }
}); });
} }
@Override @Override
public List<ItemID> selectIDs() { public Collection<ItemID> selectIDs() {
return database.query(new SelectListQuery<ItemID>() { return database.query(new SelectListQuery<ItemID, QItem>(QItem.item,
mapper.getIDMapper()) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q, QItem e) {
return "SELECT `" + ITEM_ID + "` FROM `" + TABLE + "`";
}
@Override
protected Mapper<ItemID> mapper() {
return idMapper;
} }
}); });
} }
@Override @Override
public int insertObjects(Item... items) { public int insertObjects(Item... objects) {
return database.query(new InsertUpdateQuery<Item>(items) { return database.query(new InsertQuery<Item, QItem, Object>(QItem.item,
objects) {
@Override @Override
protected String query() { protected void map(SQLInsertClause q, Item o) {
return "INSERT INTO `" + TABLE + "` (`" + ITEM_ID + "`,`" q.set(e.itemId, o.getID().getID())
+ TEMPLATE_ID + "`,`" + CHAR_ID + "`,`" + LOCATION .set(e.templateId, o.getTemplateID().getID())
+ "`,`" + PAPERDOLL + "`,`" + COUNT + "`,`" + COORD_X .set(e.characterId,
+ "`,`" + COORD_Y + "`,`" + COORD_Z (o.getOwnerID() != null ? o.getOwnerID()
+ "`) VALUES(?,?,?,?,?,?,?,?,?)"; .getID() : null))
} .set(e.location, o.getLocation())
.set(e.paperdoll, o.getPaperdoll())
@Override .set(e.count, o.getCount())
protected void parametize(PreparedStatement st, Item item) .set(e.coordX,
throws SQLException { (o.getPoint() != null ? o.getPoint().getX()
int i = 1; : null))
.set(e.coordY,
st.setInt(i++, item.getID().getID()); (o.getPoint() != null ? o.getPoint().getY()
st.setInt(i++, item.getTemplateID().getID()); : null))
if (item.getOwnerID() != null) { .set(e.coordZ,
st.setInt(i++, item.getOwnerID().getID()); (o.getPoint() != null ? o.getPoint().getZ()
} else { : null));
st.setNull(i++, Types.INTEGER);
}
st.setString(i++, item.getLocation().name());
st.setString(i++, (item.getPaperdoll() != null ? item
.getPaperdoll().name() : null));
st.setLong(i++, item.getCount());
if (item.getPoint() != null) {
st.setInt(i++, item.getPoint().getX());
st.setInt(i++, item.getPoint().getY());
st.setInt(i++, item.getPoint().getZ());
} else {
st.setNull(i++, Types.INTEGER);
st.setNull(i++, Types.INTEGER);
st.setNull(i++, Types.INTEGER);
}
} }
}); });
} }
@Override @Override
public int updateObjects(Item... items) { public int updateObjects(Item... objects) {
return database.query(new InsertUpdateQuery<Item>(items) { return database
@Override .query(new UpdateQuery<Item, QItem>(QItem.item, objects) {
protected String query() { @Override
return "UPDATE `" + TABLE + "` SET `" + CHAR_ID + "` = ?,`" protected void query(SQLUpdateClause q, Item o) {
+ LOCATION + "` = ?,`" + PAPERDOLL + "` = ?,`" + COUNT q.where(e.itemId.eq(o.getID().getID()));
+ "` = ?,`" + COORD_X + "` = ?,`" + COORD_Y + "` = ?,`" }
+ COORD_Z + "` = ? WHERE `" + ITEM_ID + "` = ?";
}
@Override @Override
protected void parametize(PreparedStatement st, Item item) protected void map(SQLUpdateClause q, Item o) {
throws SQLException { q.set(e.templateId, o.getTemplateID().getID())
int i = 1; .set(e.characterId,
(o.getOwnerID() != null ? o
// SET .getOwnerID().getID() : null))
if (item.getOwnerID() != null) { .set(e.location, o.getLocation())
st.setInt(i++, item.getOwnerID().getID()); .set(e.paperdoll, o.getPaperdoll())
} else { .set(e.count, o.getCount())
st.setNull(i++, Types.INTEGER); .set(e.coordX,
} (o.getPoint() != null ? o.getPoint()
st.setString(i++, item.getLocation().name()); .getX() : null))
st.setString(i++, (item.getPaperdoll() != null ? item .set(e.coordY,
.getPaperdoll().name() : null)); (o.getPoint() != null ? o.getPoint()
st.setLong(i++, item.getCount()); .getY() : null))
if (item.getPoint() != null) { .set(e.coordZ,
st.setInt(i++, item.getPoint().getX()); (o.getPoint() != null ? o.getPoint()
st.setInt(i++, item.getPoint().getY()); .getZ() : null));
st.setInt(i++, item.getPoint().getZ()); }
} else { });
st.setNull(i++, Types.INTEGER);
st.setNull(i++, Types.INTEGER);
st.setNull(i++, Types.INTEGER);
}
// WHERE
st.setInt(i++, item.getID().getID());
}
});
} }
@Override @Override
public int deleteObjects(Item... items) { public int deleteObjects(Item... objects) {
return database.query(new DeleteQuery<Item>(database, items) { return database
@Override .query(new DeleteQuery<Item, QItem>(QItem.item, objects) {
protected String query() { @Override
return "DELETE FROM `" + TABLE + "` WHERE `" + ITEM_ID protected void query(SQLDeleteClause q, Item o) {
+ "` = ?"; q.where(e.itemId.eq(o.getID().getID()));
} }
});
@Override
protected void parametize(PreparedStatement st, Item item)
throws SQLException {
st.setInt(1, item.getID().getID());
}
@Override
protected void dispose(Item object) {
idFactory.destroy(object.getID());
}
});
} }
@Override @Override
protected Item[] wrap(Model<?>... objects) { protected Item[] wrap(Model<?>... objects) {
final Item[] array = new Item[objects.length]; final Item[] array = new Item[objects.length];

View File

@@ -16,285 +16,157 @@
*/ */
package com.l2jserver.service.database.jdbc; package com.l2jserver.service.database.jdbc;
import java.sql.PreparedStatement; import java.util.Collection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List; import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.l2jserver.model.Model; import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterDAO; import com.l2jserver.model.dao.CharacterDAO;
import com.l2jserver.model.dao.NPCDAO; import com.l2jserver.model.dao.NPCDAO;
import com.l2jserver.model.id.object.NPCID; import com.l2jserver.model.id.object.NPCID;
import com.l2jserver.model.id.object.provider.NPCIDProvider;
import com.l2jserver.model.id.template.NPCTemplateID; import com.l2jserver.model.id.template.NPCTemplateID;
import com.l2jserver.model.id.template.provider.NPCTemplateIDProvider;
import com.l2jserver.model.template.npc.NPCTemplate;
import com.l2jserver.model.world.NPC; import com.l2jserver.model.world.NPC;
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.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.NPCMapper;
import com.l2jserver.service.database.model.QNPC;
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 * {@link CharacterDAO} implementation for JDBC
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public class JDBCNPCDAO extends AbstractJDBCDAO<NPC, NPCID> implements public class JDBCNPCDAO extends AbstractJDBCDAO<NPC, NPCID> implements NPCDAO {
NPCDAO { private final NPCMapper mapper;
/**
* The logger
*/
private final Logger log = LoggerFactory.getLogger(this.getClass());
/**
* The {@link NPCID} provider
*/
private final NPCIDProvider idProvider;
/**
* The {@link NPCTemplateID} provider
*/
private final NPCTemplateIDProvider templateIdProvider;
/**
* Character table name
*/
public static final String TABLE = "npc";
// FIELDS
public static final String NPC_ID = "npc_id";
public static final String NPC_TEMPLATE_ID = "npc_template_id";
public static final String HP = "hp";
public static final String MP = "mp";
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 RESPAWN_TIME = "respawn_time";
/** /**
* @param database * @param database
* the database service * the database service
* @param idProvider * @param mapper
* the npc id provider * the mapper
* @param templateIdProvider
* the npc template id provider
*/ */
@Inject @Inject
public JDBCNPCDAO(DatabaseService database, final NPCIDProvider idProvider, public JDBCNPCDAO(DatabaseService database, NPCMapper mapper) {
NPCTemplateIDProvider templateIdProvider) {
super(database); super(database);
this.idProvider = idProvider; this.mapper = mapper;
this.templateIdProvider = templateIdProvider;
} }
/**
* The {@link Mapper} for {@link NPCID}
*/
private final Mapper<NPCID> idMapper = new Mapper<NPCID>() {
@Override
public NPCID map(ResultSet rs) throws SQLException {
if (rs.getString(NPC_ID) == null)
return null;
return idProvider.resolveID(rs.getInt(NPC_ID));
}
};
/**
* The {@link Mapper} for {@link NPC}
*/
private final Mapper<NPC> mapper = new CachedMapper<NPC, NPCID>(database,
idMapper) {
@Override
protected NPC map(NPCID id, ResultSet rs) throws SQLException {
NPCTemplateID templateId = templateIdProvider.resolveID(rs
.getInt(NPC_TEMPLATE_ID));
NPCTemplate template = templateId.getTemplate();
if (template == null) {
log.warn("No template found for {}", templateId);
return null;
}
final NPC npc = template.create();
npc.setID(id);
if (rs.getString(HP) != null)
npc.setHP(rs.getDouble(HP));
if (rs.getString(MP) != null)
npc.setMP(rs.getDouble(MP));
npc.setPoint(Point3D.fromXYZA(rs.getInt(POINT_X),
rs.getInt(POINT_Y), rs.getInt(POINT_Z),
rs.getDouble(POINT_ANGLE)));
npc.setRespawnInterval(rs.getLong(RESPAWN_TIME));
return npc;
}
};
@Override @Override
public NPC select(final NPCID id) { public NPC select(final NPCID id) {
return database.query(new SelectSingleQuery<NPC>() { return database
@Override .query(new SelectSingleQuery<NPC, QNPC>(QNPC.npc, mapper) {
protected String query() { @Override
return "SELECT * FROM `" + TABLE + "` WHERE `" + NPC_ID protected void query(AbstractSQLQuery<?> q, QNPC e) {
+ "` = ?"; q.where(e.npcId.eq(id.getID()));
} }
});
}
@Override
public Collection<NPC> loadAll() {
return database.query(new SelectListQuery<NPC, QNPC>(QNPC.npc, mapper) {
@Override @Override
protected void parametize(PreparedStatement st) throws SQLException { protected void query(AbstractSQLQuery<?> q, QNPC e) {
st.setInt(1, id.getID());
}
@Override
protected Mapper<NPC> mapper() {
return mapper;
} }
}); });
} }
@Override @Override
public List<NPC> loadAll() { public List<NPC> selectByTemplate(final NPCTemplateID templateID) {
return database.query(new SelectListQuery<NPC>() { return database.query(new SelectListQuery<NPC, QNPC>(QNPC.npc, mapper) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q, QNPC e) {
return "SELECT * FROM `" + TABLE + "`"; q.where(e.npcTemplateId.eq(templateID.getID()));
}
@Override
protected Mapper<NPC> mapper() {
return mapper;
} }
}); });
} }
@Override @Override
public List<NPC> selectByTemplate(final NPCTemplateID template) { public Collection<NPCID> selectIDs() {
return database.query(new SelectListQuery<NPC>() { return database.query(new SelectListQuery<NPCID, QNPC>(QNPC.npc, mapper
.getIDMapper()) {
@Override @Override
protected String query() { protected void query(AbstractSQLQuery<?> q, QNPC e) {
return "SELECT * FROM `" + TABLE + "` WHERE `"
+ NPC_TEMPLATE_ID + "` = ?";
}
@Override
protected void parametize(PreparedStatement st) throws SQLException {
st.setInt(1, template.getID());
}
@Override
protected Mapper<NPC> mapper() {
return mapper;
} }
}); });
} }
@Override @Override
public List<NPCID> selectIDs() { public int insertObjects(NPC... objects) {
return database.query(new SelectListQuery<NPCID>() { return database.query(new InsertQuery<NPC, QNPC, Object>(QNPC.npc,
objects) {
@Override @Override
protected String query() { protected void map(SQLInsertClause q, NPC o) {
return "SELECT `" + NPC_ID + "` FROM `" + TABLE + "`"; q.set(e.npcId, o.getID().getID())
} .set(e.npcTemplateId, o.getTemplateID().getID())
.set(e.hp, o.getHP())
.set(e.mp, o.getMP())
.set(e.pointX,
(o.getPoint() != null ? o.getPoint().getX()
: null))
.set(e.pointY,
(o.getPoint() != null ? o.getPoint().getY()
: null))
.set(e.pointZ,
(o.getPoint() != null ? o.getPoint().getZ()
: null))
.set(e.pointAngle,
(o.getPoint() != null ? o.getPoint().getAngle()
: null))
.set(e.respawnTime, o.getRespawnInterval());
@Override
protected Mapper<NPCID> mapper() {
return idMapper;
} }
}); });
} }
@Override @Override
public int insertObjects(NPC... npcs) { public int updateObjects(NPC... objects) {
return database.query(new InsertUpdateQuery<NPC>(npcs) { return database.query(new UpdateQuery<NPC, QNPC>(QNPC.npc, objects) {
@Override @Override
protected String query() { protected void query(SQLUpdateClause q, NPC o) {
return "INSERT INTO `" + TABLE + "` (`" + NPC_ID + "`,`" q.where(e.npcId.eq(o.getID().getID()));
+ NPC_TEMPLATE_ID + "`,`" + HP + "`, `" + MP + "`,`"
+ POINT_X + "`,`" + POINT_Y + "`,`" + POINT_Z + "`,`"
+ POINT_ANGLE + "`,`" + RESPAWN_TIME
+ "`) VALUES(?,?,?,?,?,?,?,?,?)";
} }
@Override @Override
protected void parametize(PreparedStatement st, NPC npc) protected void map(SQLUpdateClause q, NPC o) {
throws SQLException { q.set(e.npcId, o.getID().getID())
int i = 1; .set(e.npcTemplateId, o.getTemplateID().getID())
.set(e.hp, o.getHP())
.set(e.mp, o.getMP())
.set(e.pointX,
(o.getPoint() != null ? o.getPoint().getX()
: null))
.set(e.pointY,
(o.getPoint() != null ? o.getPoint().getY()
: null))
.set(e.pointZ,
(o.getPoint() != null ? o.getPoint().getZ()
: null))
.set(e.pointAngle,
(o.getPoint() != null ? o.getPoint().getAngle()
: null))
st.setInt(i++, npc.getID().getID()); .set(e.respawnTime, o.getRespawnInterval());
st.setInt(i++, npc.getTemplateID().getID());
st.setDouble(i++, npc.getHP());
st.setDouble(i++, npc.getMP());
st.setInt(i++, npc.getPoint().getX());
st.setInt(i++, npc.getPoint().getY());
st.setInt(i++, npc.getPoint().getZ());
st.setDouble(i++, npc.getPoint().getAngle());
st.setLong(i++, npc.getRespawnInterval());
} }
}); });
} }
@Override @Override
public int updateObjects(NPC... npcs) { public int deleteObjects(NPC... objects) {
return database.query(new InsertUpdateQuery<NPC>(npcs) { return database.query(new DeleteQuery<NPC, QNPC>(QNPC.npc, objects) {
@Override @Override
protected String query() { protected void query(SQLDeleteClause q, NPC o) {
return "UPDATE `" + TABLE + "` SET `" + NPC_TEMPLATE_ID q.where(e.npcId.eq(o.getID().getID()));
+ "` = ?,`" + HP + "` = ?, `" + MP + "` = ?,`"
+ POINT_X + "` = ?,`" + POINT_Y + "` = ?,`" + POINT_Z
+ "` = ?,`" + POINT_ANGLE + "` = ?, `" + RESPAWN_TIME
+ "` = ? WHERE `" + NPC_ID + "` = ?";
}
@Override
protected void parametize(PreparedStatement st, NPC npc)
throws SQLException {
int i = 1;
// SET
st.setInt(i++, npc.getTemplateID().getID());
st.setDouble(i++, npc.getHP());
st.setDouble(i++, npc.getMP());
st.setInt(i++, npc.getPoint().getX());
st.setInt(i++, npc.getPoint().getY());
st.setInt(i++, npc.getPoint().getZ());
st.setDouble(i++, npc.getPoint().getAngle());
st.setLong(i++, npc.getRespawnInterval());
// WHERE
st.setInt(i++, npc.getID().getID());
}
});
}
@Override
public int deleteObjects(NPC... npcs) {
return database.query(new InsertUpdateQuery<NPC>(npcs) {
@Override
protected String query() {
return "DELETE FROM `" + TABLE + "` WHERE `" + NPC_ID + "` = ?";
}
@Override
protected void parametize(PreparedStatement st, NPC npc)
throws SQLException {
st.setInt(1, npc.getID().getID());
} }
}); });
} }

View File

@@ -0,0 +1,76 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.mapper;
import com.google.inject.Inject;
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.service.database.dao.DatabaseRow;
import com.l2jserver.service.database.dao.Mapper;
import com.l2jserver.service.database.model.QCharacterFriend;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class CharacterFriendMapper implements
Mapper<CharacterFriend, QCharacterFriend> {
private final Mapper<FriendID, QCharacterFriend> idMapper = new Mapper<FriendID, QCharacterFriend>() {
@Override
public FriendID map(QCharacterFriend e, DatabaseRow row) {
return idProvider.createID(
charIdProvider.resolveID(row.get(e.characterId)),
charIdProvider.resolveID(row.get(e.characterIdFriend)));
}
};
/**
* The {@link CharacterID} provider
*/
private final FriendIDProvider idProvider;
/**
* The {@link CharacterID} provider
*/
private final CharacterIDProvider charIdProvider;
/**
* @param idProvider
* the {@link FriendID} provider
* @param charIdProvider
* the character id provider
*/
@Inject
public CharacterFriendMapper(FriendIDProvider idProvider,
final CharacterIDProvider charIdProvider) {
this.idProvider = idProvider;
this.charIdProvider = charIdProvider;
}
@Override
public CharacterFriend map(QCharacterFriend e, DatabaseRow row) {
return new CharacterFriend(idProvider.createID(
charIdProvider.resolveID(row.get(e.characterId)),
charIdProvider.resolveID(row.get(e.characterIdFriend))));
}
public Mapper<FriendID, QCharacterFriend> getIDMapper() {
return idMapper;
}
}

View File

@@ -0,0 +1,129 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.mapper;
import com.google.inject.Inject;
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.character.CharacterClass;
import com.l2jserver.model.template.character.CharacterTemplate;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.database.dao.DatabaseRow;
import com.l2jserver.service.database.dao.Mapper;
import com.l2jserver.service.database.model.QCharacter;
import com.l2jserver.util.geometry.Point3D;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class CharacterMapper implements Mapper<L2Character, QCharacter> {
private final Mapper<CharacterID, QCharacter> idMapper = new Mapper<CharacterID, QCharacter>() {
@Override
public CharacterID map(QCharacter e, DatabaseRow row) {
return idProvider.resolveID(row.get(e.characterId));
}
};
/**
* The {@link CharacterID} provider
*/
private final CharacterIDProvider idProvider;
/**
* The {@link CharacterTemplateID} provider
*/
private final CharacterTemplateIDProvider templateIdProvider;
/**
* The {@link AccountID} provider
*/
private final AccountIDProvider accountIdProvider;
/**
* The {@link ClanID} provider
*/
private final ClanIDProvider clanIdProvider;
/**
* @param idProvider
* the {@link CharacterID} provider
* @param templateIdProvider
* the {@link CharacterTemplateID} provider
* @param accountIdProvider
* the {@link AccountID} provider
* @param clanIdProvider
* the {@link ClanID} provider
*/
@Inject
public CharacterMapper(final CharacterIDProvider idProvider,
CharacterTemplateIDProvider templateIdProvider,
AccountIDProvider accountIdProvider, ClanIDProvider clanIdProvider) {
this.idProvider = idProvider;
this.templateIdProvider = templateIdProvider;
this.accountIdProvider = accountIdProvider;
this.clanIdProvider = clanIdProvider;
}
@Override
public L2Character map(QCharacter e, DatabaseRow row) {
final CharacterClass charClass = row.get(e.characterClass);
final CharacterTemplateID templateId = templateIdProvider
.resolveID(charClass.id);
final CharacterTemplate template = templateId.getTemplate();
final L2Character character = template.create();
character.setID(idProvider.resolveID(row.get(e.characterId)));
character
.setAccountID(accountIdProvider.resolveID(row.get(e.accountId)));
if (!row.isNull(e.clanId))
character.setClanID(clanIdProvider.resolveID(row.get(e.clanId)));
character.setName(row.get(e.name));
character.setRace(row.get(e.race));
character.setCharacterClass(row.get(e.characterClass));
character.setSex(row.get(e.sex));
character.setLevel(row.get(e.level));
character.setExperience(row.get(e.experience));
character.setSP(row.get(e.sp));
character.setHP(row.get(e.hp));
character.setMP(row.get(e.mp));
character.setCP(row.get(e.cp));
character.setPoint(Point3D.fromXYZA(row.get(e.pointX),
row.get(e.pointY), row.get(e.pointZ), row.get(e.pointAngle)));
// appearance
character.getAppearance().setHairStyle(row.get(e.appearanceHairStyle));
character.getAppearance().setHairColor(row.get(e.appearanceHairColor));
character.getAppearance().setFace(row.get(e.apperanceFace));
return character;
}
public Mapper<CharacterID, QCharacter> getIDMapper() {
return idMapper;
}
}

View File

@@ -0,0 +1,104 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.mapper;
import com.google.inject.Inject;
import com.l2jserver.model.game.CharacterShortcut;
import com.l2jserver.model.game.CharacterShortcut.ShortcutType;
import com.l2jserver.model.id.CharacterShortcutID;
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.service.database.dao.DatabaseRow;
import com.l2jserver.service.database.dao.Mapper;
import com.l2jserver.service.database.model.QCharacterShortcut;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class CharacterShortcutMapper implements
Mapper<CharacterShortcut, QCharacterShortcut> {
private final Mapper<CharacterShortcutID, QCharacterShortcut> idMapper = new Mapper<CharacterShortcutID, QCharacterShortcut>() {
@Override
public CharacterShortcutID map(QCharacterShortcut e, DatabaseRow row) {
return idProvider.resolveID(row.get(e.shortcutId));
}
};
/**
* The {@link CharacterShortcutID} provider
*/
private final CharacterShortcutIDProvider idProvider;
/**
* The {@link CharacterID} provider
*/
private final CharacterIDProvider charIdProvider;
/**
* The {@link ItemID} provider
*/
private final ItemIDProvider itemIdProvider;
/**
* @param idProvider
* the {@link CharacterID} provider
* @param charIdProvider
* the character ID provider
* @param itemIdProvider
* the item ID provider
*
*/
@Inject
public CharacterShortcutMapper(
final CharacterShortcutIDProvider idProvider,
CharacterIDProvider charIdProvider, ItemIDProvider itemIdProvider) {
this.idProvider = idProvider;
this.charIdProvider = charIdProvider;
this.itemIdProvider = itemIdProvider;
}
@Override
public CharacterShortcut map(QCharacterShortcut e, DatabaseRow row) {
final CharacterShortcut shortcut = new CharacterShortcut();
shortcut.setID(idProvider.resolveID(row.get(e.shortcutId)));
final CharacterID charId = charIdProvider.resolveID(row
.get(e.characterId));
shortcut.setCharacterID(charId);
// resolve type
final ShortcutType type = row.get(e.type);
shortcut.setType(type);
switch (type) {
case ITEM:
final ItemID itemId = itemIdProvider.resolveID(row.get(e.objectId));
shortcut.setItemID(itemId);
break;
}
shortcut.setPage(row.get(e.page));
shortcut.setSlot(row.get(e.slot));
return shortcut;
}
public Mapper<CharacterShortcutID, QCharacterShortcut> getIDMapper() {
return idMapper;
}
}

View File

@@ -0,0 +1,89 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.mapper;
import com.google.inject.Inject;
import com.l2jserver.model.id.ChatMessageID;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.id.object.provider.CharacterIDProvider;
import com.l2jserver.model.id.provider.ChatMessageIDProvider;
import com.l2jserver.model.server.ChatMessage;
import com.l2jserver.service.database.dao.DatabaseRow;
import com.l2jserver.service.database.dao.Mapper;
import com.l2jserver.service.database.model.QLogChat;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class ChatMessageMapper implements Mapper<ChatMessage, QLogChat> {
private final Mapper<ChatMessageID, QLogChat> idMapper = new Mapper<ChatMessageID, QLogChat>() {
@Override
public ChatMessageID map(QLogChat e, DatabaseRow row) {
return idProvider.resolveID(row.get(e.messageId));
}
};
/**
* The {@link ChatMessageID} provider
*/
private final ChatMessageIDProvider idProvider;
/**
* The {@link CharacterID} provider
*/
private final CharacterIDProvider charIdProvider;
/**
* @param idProvider
* the {@link CharacterID} provider
* @param charIdProvider
* the character ID provider
*
*/
@Inject
public ChatMessageMapper(final ChatMessageIDProvider idProvider,
CharacterIDProvider charIdProvider) {
this.idProvider = idProvider;
this.charIdProvider = charIdProvider;
}
@Override
public ChatMessage map(QLogChat e, DatabaseRow row) {
final ChatMessage message = new ChatMessage();
message.setID(idProvider.resolveID(row.get(e.messageId)));
message.setType(row.get(e.type));
switch (message.getType()) {
case SHOUT:
message.setTarget(charIdProvider.resolveID(row.get(e.channelId)));
break;
default:
message.setChannelID(row.get(e.channelId));
break;
}
message.setSender(charIdProvider.resolveID(row.get(e.sender)));
message.setDate(row.get(e.date));
message.setMessage(row.get(e.message));
return message;
}
public Mapper<ChatMessageID, QLogChat> getIDMapper() {
return idMapper;
}
}

View File

@@ -0,0 +1,75 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.mapper;
import com.google.inject.Inject;
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.world.Clan;
import com.l2jserver.service.database.dao.DatabaseRow;
import com.l2jserver.service.database.dao.Mapper;
import com.l2jserver.service.database.model.QClan;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class ClanMapper implements Mapper<Clan, QClan> {
private final Mapper<ClanID, QClan> idMapper = new Mapper<ClanID, QClan>() {
@Override
public ClanID map(QClan e, DatabaseRow row) {
return idProvider.resolveID(row.get(e.clanId));
}
};
/**
* The {@link ClanID} provider
*/
private final ClanIDProvider idProvider;
/**
* The {@link CharacterID} provider
*/
private final CharacterIDProvider charIdProvider;
/**
* @param idProvider
* the {@link ClanID} provider
* @param charIdProvider
* the character ID provider
*/
@Inject
public ClanMapper(final ClanIDProvider idProvider,
CharacterIDProvider charIdProvider) {
this.idProvider = idProvider;
this.charIdProvider = charIdProvider;
}
@Override
public Clan map(QClan e, DatabaseRow row) {
final Clan clan = new Clan();
clan.setID(idProvider.resolveID(row.get(e.clanId)));
clan.setID(charIdProvider.resolveID(row.get(e.characterIdLeader)));
return clan;
}
public Mapper<ClanID, QClan> getIDMapper() {
return idMapper;
}
}

View File

@@ -0,0 +1,119 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.mapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.l2jserver.model.id.CharacterShortcutID;
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.template.ItemTemplateID;
import com.l2jserver.model.id.template.provider.ItemTemplateIDProvider;
import com.l2jserver.model.template.item.ItemTemplate;
import com.l2jserver.model.world.Item;
import com.l2jserver.service.database.dao.DatabaseRow;
import com.l2jserver.service.database.dao.Mapper;
import com.l2jserver.service.database.model.QItem;
import com.l2jserver.util.geometry.Coordinate;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class ItemMapper implements Mapper<Item, QItem> {
/**
* The logger
*/
private final Logger log = LoggerFactory.getLogger(this.getClass());
private final Mapper<ItemID, QItem> idMapper = new Mapper<ItemID, QItem>() {
@Override
public ItemID map(QItem e, DatabaseRow row) {
return idProvider.resolveID(row.get(e.itemId));
}
};
/**
* The {@link CharacterShortcutID} provider
*/
private final ItemIDProvider idProvider;
/**
* The {@link ItemTemplateID} provider
*/
private final ItemTemplateIDProvider templateIdProvider;
/**
* The {@link CharacterID} provider
*/
private final CharacterIDProvider charIdProvider;
/**
* @param idProvider
* the {@link ItemID} provider
* @param templateIdProvider
* the item template id provider
* @param charIdProvider
* the character ID provider
*/
@Inject
public ItemMapper(final ItemIDProvider idProvider,
ItemTemplateIDProvider templateIdProvider,
CharacterIDProvider charIdProvider) {
this.idProvider = idProvider;
this.templateIdProvider = templateIdProvider;
this.charIdProvider = charIdProvider;
}
@Override
public Item map(QItem e, DatabaseRow row) {
final ItemID id = idProvider.resolveID(row.get(e.itemId));
final ItemTemplateID templateId = templateIdProvider.resolveID(row
.get(e.templateId));
final ItemTemplate template = templateId.getTemplate();
if (template == null) {
log.warn("No template found for {} while loading {}", templateId,
id);
return null;
}
final Item item = template.create();
item.setID(id);
if (!row.isNull(e.characterId))
item.setOwnerID(charIdProvider.resolveID(row.get(e.characterId)));
if (!row.isNull(e.location))
item.setLocation(row.get(e.location));
if (!row.isNull(e.paperdoll))
item.setPaperdoll(row.get(e.paperdoll));
item.setCount(row.get(e.count));
if (!row.isNull(e.coordX) && !row.isNull(e.coordY)
&& !row.isNull(e.coordZ))
item.setPosition(Coordinate.fromXYZ(row.get(e.coordX),
row.get(e.coordY), row.get(e.coordZ)));
return item;
}
public Mapper<ItemID, QItem> getIDMapper() {
return idMapper;
}
}

View File

@@ -0,0 +1,105 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.mapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.l2jserver.model.id.object.NPCID;
import com.l2jserver.model.id.object.provider.NPCIDProvider;
import com.l2jserver.model.id.template.NPCTemplateID;
import com.l2jserver.model.id.template.provider.NPCTemplateIDProvider;
import com.l2jserver.model.template.npc.NPCTemplate;
import com.l2jserver.model.world.NPC;
import com.l2jserver.service.database.dao.DatabaseRow;
import com.l2jserver.service.database.dao.Mapper;
import com.l2jserver.service.database.model.QNPC;
import com.l2jserver.util.geometry.Point3D;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class NPCMapper implements Mapper<NPC, QNPC> {
/**
* The logger
*/
private final Logger log = LoggerFactory.getLogger(this.getClass());
private final Mapper<NPCID, QNPC> idMapper = new Mapper<NPCID, QNPC>() {
@Override
public NPCID map(QNPC e, DatabaseRow row) {
return idProvider.resolveID(row.get(e.npcId));
}
};
/**
* The {@link NPCID} provider
*/
private final NPCIDProvider idProvider;
/**
* The {@link NPCTemplateID} provider
*/
private final NPCTemplateIDProvider templateIdProvider;
/**
* @param idProvider
* the {@link NPCID} provider
* @param templateIdProvider
* the item template id provider
*/
@Inject
public NPCMapper(final NPCIDProvider idProvider,
NPCTemplateIDProvider templateIdProvider) {
this.idProvider = idProvider;
this.templateIdProvider = templateIdProvider;
}
@Override
public NPC map(QNPC e, DatabaseRow row) {
final NPCID id = idProvider.resolveID(row.get(e.npcId));
NPCTemplateID templateId = templateIdProvider.resolveID(row
.get(e.npcTemplateId));
NPCTemplate template = templateId.getTemplate();
if (template == null) {
log.warn("No template found for {}", templateId);
return null;
}
final NPC npc = template.create();
npc.setID(id);
if (!row.isNull(e.hp))
npc.setHP(row.get(e.hp));
if (!row.isNull(e.mp))
npc.setMP(row.get(e.mp));
if (!row.isNull(e.pointX) && !row.isNull(e.pointY)
&& !row.isNull(e.pointZ) && !row.isNull(e.pointAngle))
npc.setPoint(Point3D.fromXYZA(row.get(e.pointX), row.get(e.pointY),
row.get(e.pointZ), row.get(e.pointAngle)));
npc.setRespawnInterval(row.get(e.respawnTime));
return npc;
}
public Mapper<NPCID, QNPC> getIDMapper() {
return idMapper;
}
}

View File

@@ -0,0 +1,45 @@
package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.model.game.Skill;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.sql.RelationalPathBase;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;
import com.mysema.query.types.path.NumberPath;
/**
* Maps <code>actor_skill</code> table into type-safe java objects
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class QActorSkill extends RelationalPathBase<Skill> {
private static final long serialVersionUID = -146336131;
public static final QActorSkill actorSkill = new QActorSkill("actor_skill");
public final NumberPath<Integer> actorId = createNumber("actor_id",
Integer.class);
public final NumberPath<Integer> level = createNumber("level",
Integer.class);
public final NumberPath<Integer> skillId = createNumber("skill_id",
Integer.class);
public final PrimaryKey<Skill> primary = createPrimaryKey(actorId, skillId);
public QActorSkill(String variable) {
super(Skill.class, forVariable(variable), "null", "actor_skill");
}
public QActorSkill(Path<? extends Skill> entity) {
super(entity.getType(), entity.getMetadata(), "null", "actor_skill");
}
public QActorSkill(PathMetadata<?> metadata) {
super(Skill.class, metadata, "null", "actor_skill");
}
}

View File

@@ -0,0 +1,86 @@
package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
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.L2Character;
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.mysema.query.sql.PrimaryKey;
import com.mysema.query.sql.RelationalPathBase;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;
import com.mysema.query.types.path.EnumPath;
import com.mysema.query.types.path.NumberPath;
import com.mysema.query.types.path.StringPath;
/**
* Maps <code>character</code> table into type-safe java objects
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class QCharacter extends RelationalPathBase<L2Character> {
private static final long serialVersionUID = -59499032;
public static final QCharacter character = new QCharacter("l2character");
public final NumberPath<Integer> characterId = createNumber("character_id",
Integer.class);
public final StringPath accountId = createString("account_id");
public final NumberPath<Integer> clanId = createNumber("clan_id",
Integer.class);
public final StringPath name = createString("name");
public final EnumPath<CharacterRace> race = createEnum("race",
CharacterRace.class);
public final EnumPath<ActorSex> sex = createEnum("sex", ActorSex.class);
public final EnumPath<CharacterClass> characterClass = createEnum("class",
CharacterClass.class);
public final NumberPath<Integer> level = createNumber("level",
Integer.class);
public final NumberPath<Long> experience = createNumber("experience",
Long.class);
public final NumberPath<Integer> sp = createNumber("sp", Integer.class);
public final NumberPath<Double> cp = createNumber("cp", Double.class);
public final NumberPath<Double> hp = createNumber("hp", Double.class);
public final NumberPath<Double> mp = createNumber("mp", Double.class);
public final NumberPath<Double> pointAngle = createNumber("point_angle",
Double.class);
public final NumberPath<Integer> pointX = createNumber("point_x",
Integer.class);
public final NumberPath<Integer> pointY = createNumber("point_y",
Integer.class);
public final NumberPath<Integer> pointZ = createNumber("point_z",
Integer.class);
public final EnumPath<CharacterHairColor> appearanceHairColor = createEnum(
"appearance_hair_color", CharacterHairColor.class);
public final EnumPath<CharacterHairStyle> appearanceHairStyle = createEnum(
"appearance_hair_style", CharacterHairStyle.class);
public final EnumPath<CharacterFace> apperanceFace = createEnum(
"apperance_face", CharacterFace.class);
public final PrimaryKey<L2Character> primary = createPrimaryKey(characterId);
public QCharacter(String variable) {
super(L2Character.class, forVariable(variable), "null", "character");
}
public QCharacter(Path<? extends L2Character> entity) {
super(entity.getType(), entity.getMetadata(), "null", "character");
}
public QCharacter(PathMetadata<?> metadata) {
super(L2Character.class, metadata, "null", "character");
}
}

View File

@@ -0,0 +1,45 @@
package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.model.game.CharacterFriend;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;
import com.mysema.query.types.path.NumberPath;
/**
* Maps <code>character_friend</code> table into type-safe java objects
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class QCharacterFriend extends
com.mysema.query.sql.RelationalPathBase<CharacterFriend> {
private static final long serialVersionUID = 1488651942;
public static final QCharacterFriend characterFriend = new QCharacterFriend(
"character_friend");
public final NumberPath<Integer> characterId = createNumber("character_id",
Integer.class);
public final NumberPath<Integer> characterIdFriend = createNumber(
"character_id_friend", Integer.class);
public final PrimaryKey<CharacterFriend> primary = createPrimaryKey(
characterId, characterIdFriend);
public QCharacterFriend(String variable) {
super(CharacterFriend.class, forVariable(variable), "null",
"character_friend");
}
public QCharacterFriend(Path<? extends CharacterFriend> entity) {
super(entity.getType(), entity.getMetadata(), "null",
"character_friend");
}
public QCharacterFriend(PathMetadata<?> metadata) {
super(CharacterFriend.class, metadata, "null", "character_friend");
}
}

View File

@@ -0,0 +1,55 @@
package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.model.game.CharacterShortcut;
import com.l2jserver.model.game.CharacterShortcut.ShortcutType;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;
import com.mysema.query.types.path.EnumPath;
import com.mysema.query.types.path.NumberPath;
/**
* Maps <code>character_shortcut</code> table into type-safe java objects
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class QCharacterShortcut extends com.mysema.query.sql.RelationalPathBase<CharacterShortcut> {
private static final long serialVersionUID = 1450964558;
public static final QCharacterShortcut characterShortcut = new QCharacterShortcut("character_shortcut");
public final NumberPath<Integer> characterId = createNumber("character_id", Integer.class);
public final NumberPath<Integer> characterType = createNumber("character_type", Integer.class);
public final NumberPath<Integer> level = createNumber("level", Integer.class);
public final NumberPath<Integer> objectId = createNumber("object_id", Integer.class);
public final NumberPath<Integer> page = createNumber("page", Integer.class);
public final NumberPath<Integer> shortcutId = createNumber("shortcut_id", Integer.class);
public final NumberPath<Integer> slot = createNumber("slot", Integer.class);
public final EnumPath<ShortcutType> type = createEnum("type", ShortcutType.class);
public final PrimaryKey<CharacterShortcut> primary = createPrimaryKey(shortcutId);
public QCharacterShortcut(String variable) {
super(CharacterShortcut.class, forVariable(variable), "null", "character_shortcut");
}
public QCharacterShortcut(Path<? extends CharacterShortcut> entity) {
super(entity.getType(), entity.getMetadata(), "null", "character_shortcut");
}
public QCharacterShortcut(PathMetadata<?> metadata) {
super(CharacterShortcut.class, metadata, "null", "character_shortcut");
}
}

View File

@@ -0,0 +1,41 @@
package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.model.world.Clan;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;
import com.mysema.query.types.path.NumberPath;
/**
* Maps <code>clan</code> table into type-safe java objects
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class QClan extends com.mysema.query.sql.RelationalPathBase<Clan> {
private static final long serialVersionUID = 1592083511;
public static final QClan clan = new QClan("clan");
public final NumberPath<Integer> characterIdLeader = createNumber("character_id_leader", Integer.class);
public final NumberPath<Integer> clanId = createNumber("clan_id", Integer.class);
public final PrimaryKey<Clan> primary = createPrimaryKey(clanId);
public QClan(String variable) {
super(Clan.class, forVariable(variable), "null", "clan");
}
public QClan(Path<? extends Clan> entity) {
super(entity.getType(), entity.getMetadata(), "null", "clan");
}
public QClan(PathMetadata<?> metadata) {
super(Clan.class, metadata, "null", "clan");
}
}

View File

@@ -0,0 +1,65 @@
package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
import com.l2jserver.model.world.character.CharacterInventory.ItemLocation;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;
import com.mysema.query.types.path.EnumPath;
import com.mysema.query.types.path.NumberPath;
/**
* Maps <code>item</code> table into type-safe java objects
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class QItem extends com.mysema.query.sql.RelationalPathBase<Item> {
private static final long serialVersionUID = 1592270068;
public static final QItem item = new QItem("item");
public final NumberPath<Integer> characterId = createNumber("character_id",
Integer.class);
public final NumberPath<Integer> coordX = createNumber("coord_x",
Integer.class);
public final NumberPath<Integer> coordY = createNumber("coord_y",
Integer.class);
public final NumberPath<Integer> coordZ = createNumber("coord_z",
Integer.class);
public final NumberPath<Long> count = createNumber("count",
Long.class);
public final NumberPath<Integer> itemId = createNumber("item_id",
Integer.class);
public final EnumPath<ItemLocation> location = createEnum("location",
ItemLocation.class);
public final EnumPath<InventoryPaperdoll> paperdoll = createEnum(
"paperdoll", InventoryPaperdoll.class);
public final NumberPath<Integer> templateId = createNumber("template_id",
Integer.class);
public final PrimaryKey<Item> primary = createPrimaryKey(itemId);
public QItem(String variable) {
super(Item.class, forVariable(variable), "null", "item");
}
public QItem(Path<? extends Item> entity) {
super(entity.getType(), entity.getMetadata(), "null", "item");
}
public QItem(PathMetadata<?> metadata) {
super(Item.class, metadata, "null", "item");
}
}

View File

@@ -0,0 +1,57 @@
package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import java.util.Date;
import com.l2jserver.model.server.ChatMessage;
import com.l2jserver.service.game.chat.ChatMessageType;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;
import com.mysema.query.types.path.DateTimePath;
import com.mysema.query.types.path.EnumPath;
import com.mysema.query.types.path.NumberPath;
import com.mysema.query.types.path.StringPath;
/**
* Maps <code>log_chat</code> table into type-safe java objects
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class QLogChat extends com.mysema.query.sql.RelationalPathBase<ChatMessage> {
private static final long serialVersionUID = -76124357;
public static final QLogChat logChat = new QLogChat("log_chat");
public final NumberPath<Integer> channelId = createNumber("channel_id",
Integer.class);
public final DateTimePath<Date> date = createDateTime("date", Date.class);
public final StringPath message = createString("message");
public final NumberPath<Integer> messageId = createNumber("message_id",
Integer.class);
public final NumberPath<Integer> sender = createNumber("sender",
Integer.class);
public final EnumPath<ChatMessageType> type = createEnum("type",
ChatMessageType.class);
public final PrimaryKey<ChatMessage> primary = createPrimaryKey(messageId);
public QLogChat(String variable) {
super(ChatMessage.class, forVariable(variable), "null", "log_chat");
}
public QLogChat(Path<? extends ChatMessage> entity) {
super(entity.getType(), entity.getMetadata(), "null", "log_chat");
}
public QLogChat(PathMetadata<?> metadata) {
super(ChatMessage.class, metadata, "null", "log_chat");
}
}

View File

@@ -0,0 +1,55 @@
package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.model.world.NPC;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;
import com.mysema.query.types.path.NumberPath;
/**
* Maps <code>npc</code> table into type-safe java objects
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class QNPC extends com.mysema.query.sql.RelationalPathBase<NPC> {
private static final long serialVersionUID = 2129578208;
public static final QNPC npc = new QNPC("npc");
public final NumberPath<Double> hp = createNumber("hp", Double.class);
public final NumberPath<Double> mp = createNumber("mp", Double.class);
public final NumberPath<Integer> npcId = createNumber("npc_id", Integer.class);
public final NumberPath<Integer> npcTemplateId = createNumber("npc_template_id", Integer.class);
public final NumberPath<Double> pointAngle = createNumber("point_angle", Double.class);
public final NumberPath<Integer> pointX = createNumber("point_x", Integer.class);
public final NumberPath<Integer> pointY = createNumber("point_y", Integer.class);
public final NumberPath<Integer> pointZ = createNumber("point_z", Integer.class);
public final NumberPath<Long> respawnTime = createNumber("respawn_time", Long.class);
public final PrimaryKey<NPC> primary = createPrimaryKey(npcId);
public QNPC(String variable) {
super(NPC.class, forVariable(variable), "null", "npc");
}
public QNPC(Path<? extends NPC> entity) {
super(entity.getType(), entity.getMetadata(), "null", "npc");
}
public QNPC(PathMetadata<?> metadata) {
super(NPC.class, metadata, "null", "npc");
}
}

View File

@@ -1,465 +0,0 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.orientdb;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import com.google.inject.Inject;
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.AbstractOrientDatabaseService.CachedMapper;
import com.l2jserver.service.database.AbstractOrientDatabaseService.InsertUpdateQuery;
import com.l2jserver.service.database.AbstractOrientDatabaseService.Mapper;
import com.l2jserver.service.database.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.AbstractOrientDatabaseService.SelectSingleQuery;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.util.geometry.Point3D;
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;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class OrientDBCharacterDAO extends
AbstractOrientDBDAO<L2Character, CharacterID> implements CharacterDAO {
/**
* The {@link CharacterID} factory
*/
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 CLASS_NAME = L2Character.class.getSimpleName();
// 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";
/**
* The mapper for {@link CharacterID}
*/
private final Mapper<CharacterID> idMapper = new Mapper<CharacterID>() {
@Override
public CharacterID map(ODocument document) throws SQLException {
return idFactory.resolveID((Integer) document.field(CHAR_ID));
}
};
/**
* The {@link Mapper} for {@link L2Character}
*/
private final Mapper<L2Character> mapper = new CachedMapper<L2Character, CharacterID>(
database, idMapper) {
@Override
protected L2Character map(CharacterID id, ODocument document)
throws SQLException {
final CharacterClass charClass = (CharacterClass) document
.field(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((String) document
.field(ACCOUNT_ID)));
if (document.containsField(CLAN_ID))
character.setClanID(clanIdFactory.resolveID((Integer) document
.field(CLAN_ID)));
character.setName((String) document.field(NAME));
character.setRace((CharacterRace) document.field(RACE));
character.setCharacterClass((CharacterClass) document.field(CLASS));
character.setSex((ActorSex) document.field(SEX));
character.setLevel((Integer) document.field(LEVEL));
character.setExperience((Long) document.field(EXPERIENCE));
character.setSP((Integer) document.field(SP));
character.setHP((Double) document.field(HP));
character.setMP((Double) document.field(MP));
character.setCP((Double) document.field(CP));
character.setPoint(Point3D.fromXYZA(
(Integer) document.field(POINT_X),
(Integer) document.field(POINT_Y),
(Integer) document.field(POINT_Z),
(Double) document.field(POINT_ANGLE)));
// appearance
character.getAppearance().setHairStyle(
(CharacterHairStyle) document.field(APPEARANCE_HAIR_STYLE));
character.getAppearance().setHairColor(
(CharacterHairColor) document.field(APPEARANCE_HAIR_COLOR));
character.getAppearance().setFace(
(CharacterFace) document.field(APPEARANCE_FACE));
return character;
}
};
/**
* @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
*/
@Inject
protected OrientDBCharacterDAO(DatabaseService database,
final CharacterIDProvider idFactory,
CharacterTemplateIDProvider templateIdFactory,
AccountIDProvider accountIdFactory, ClanIDProvider clanIdFactory) {
super(database);
this.idFactory = idFactory;
this.templateIdFactory = templateIdFactory;
this.accountIdFactory = accountIdFactory;
this.clanIdFactory = clanIdFactory;
}
@Override
public L2Character select(final CharacterID id) {
return database.query(new SelectSingleQuery<L2Character>() {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database) {
return new ONativeSynchQuery<OQueryContextNative>(database,
CLASS_NAME, new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative criteria) {
return criteria.field(CHAR_ID).eq(id.getID()).go();
}
};
}
@Override
protected Mapper<L2Character> mapper() {
return mapper;
}
});
}
@Override
public Collection<CharacterID> selectIDs() {
return database.query(new SelectListQuery<CharacterID>() {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database) {
return new ONativeSynchQuery<OQueryContextNative>(database,
CLASS_NAME, new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative criteria) {
return true;
};
};
}
@Override
protected Mapper<CharacterID> mapper() {
return idMapper;
}
});
}
@Override
public int insertObjects(L2Character... objects) {
return database.query(new InsertUpdateQuery<L2Character>(objects) {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database, L2Character object) {
return null;
}
@Override
protected ODocument update(ODocument document, L2Character character)
throws SQLException {
return null;
}
@Override
protected ODocument insert(ODocument document, L2Character character)
throws SQLException {
final CharacterAppearance appearance = character
.getAppearance();
document.field(CHAR_ID, character.getID().getID());
document.field(ACCOUNT_ID, character.getAccountID().getID());
if (character.getClanID() != null)
document.field(CLAN_ID, character.getClanID().getID());
document.field(NAME, character.getName());
document.field(RACE, character.getRace().name());
document.field(CLASS, character.getCharacterClass().name());
document.field(SEX, character.getSex().name());
document.field(LEVEL, character.getLevel());
document.field(EXPERIENCE, character.getExperience());
document.field(SP, character.getSP());
document.field(HP, character.getHP());
document.field(MP, character.getMP());
document.field(CP, character.getCP());
document.field(POINT_X, character.getPoint().getX());
document.field(POINT_Y, character.getPoint().getY());
document.field(POINT_Z, character.getPoint().getZ());
document.field(POINT_ANGLE, character.getPoint().getAngle());
// appearance
document.field(APPEARANCE_HAIR_STYLE, appearance.getHairStyle()
.name());
document.field(APPEARANCE_HAIR_COLOR, appearance.getHairColor()
.name());
document.field(APPEARANCE_FACE, appearance.getFace().name());
return document;
}
});
}
@Override
public int updateObjects(final L2Character... characters) {
return database.query(new InsertUpdateQuery<L2Character>(characters) {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database, final L2Character character) {
return new ONativeSynchQuery<OQueryContextNative>(database,
CLASS_NAME, new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative criteria) {
return criteria.field(CHAR_ID)
.eq(character.getID().getID()).go();
};
};
}
@Override
protected ODocument update(ODocument document, L2Character character)
throws SQLException {
final CharacterAppearance appearance = character
.getAppearance();
document.field(ACCOUNT_ID, character.getAccountID().getID());
if (character.getClanID() != null)
document.field(CLAN_ID, character.getClanID().getID());
document.field(NAME, character.getName());
document.field(RACE, character.getRace().name());
document.field(CLASS, character.getCharacterClass().name());
document.field(SEX, character.getSex().name());
document.field(LEVEL, character.getLevel());
document.field(EXPERIENCE, character.getExperience());
document.field(SP, character.getSP());
document.field(HP, character.getHP());
document.field(MP, character.getMP());
document.field(CP, character.getCP());
document.field(POINT_X, character.getPoint().getX());
document.field(POINT_Y, character.getPoint().getY());
document.field(POINT_Z, character.getPoint().getZ());
document.field(POINT_ANGLE, character.getPoint().getAngle());
// appearance
document.field(APPEARANCE_HAIR_STYLE, appearance.getHairStyle()
.name());
document.field(APPEARANCE_HAIR_COLOR, appearance.getHairColor()
.name());
document.field(APPEARANCE_FACE, appearance.getFace().name());
return document;
}
@Override
protected ODocument insert(ODocument document, L2Character character)
throws SQLException {
return null;
}
});
}
@Override
public int deleteObjects(L2Character... objects) {
return database.query(new InsertUpdateQuery<L2Character>(objects) {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database, final L2Character character) {
return new ONativeSynchQuery<OQueryContextNative>(database,
CLASS_NAME, new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative criteria) {
return criteria.field(CHAR_ID)
.eq(character.getID().getID()).go();
};
};
}
@Override
protected ODocument update(ODocument document, L2Character character)
throws SQLException {
document.delete();
return null;
}
@Override
protected ODocument insert(ODocument document, L2Character character)
throws SQLException {
return null;
}
});
}
@Override
public void load(Clan clan) {
}
@Override
public L2Character selectByName(final String name) {
return database.query(new SelectSingleQuery<L2Character>() {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database) {
return new ONativeSynchQuery<OQueryContextNative>(database,
CLASS_NAME, new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative criteria) {
return criteria.field(NAME).eq(name).go();
};
};
}
@Override
protected Mapper<L2Character> mapper() {
return mapper;
}
});
}
@Override
public List<L2Character> selectByAccount(final AccountID account) {
return database.query(new SelectListQuery<L2Character>() {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database) {
return new ONativeSynchQuery<OQueryContextNative>(database,
CLASS_NAME, new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative criteria) {
return criteria.field(ACCOUNT_ID).eq(account.getID())
.go();
};
};
}
@Override
protected Mapper<L2Character> mapper() {
return mapper;
}
});
}
@Override
protected L2Character[] wrap(Model<?>... objects) {
final L2Character[] array = new L2Character[objects.length];
int i = 0;
for (final Model<?> object : objects) {
array[i++] = (L2Character) object;
}
return array;
}
}

View File

@@ -1,285 +0,0 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.orientdb;
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.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.AbstractOrientDatabaseService.CachedMapper;
import com.l2jserver.service.database.AbstractOrientDatabaseService.InsertUpdateQuery;
import com.l2jserver.service.database.AbstractOrientDatabaseService.Mapper;
import com.l2jserver.service.database.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.AbstractOrientDatabaseService.SelectSingleQuery;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.jdbc.JDBCCharacterDAO;
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;
/**
* {@link CharacterFriendDAO} implementation for JDBC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBCharacterFriendDAO extends
AbstractOrientDBDAO<CharacterFriend, FriendID> implements
CharacterFriendDAO {
/**
* The {@link FriendID} provider
*/
private final FriendIDProvider idProvider;
/**
* The {@link CharacterID} provider
*/
private final CharacterIDProvider charIdProvider;
/**
* Character table name
*/
public static final String CLASS_NAME = CharacterFriend.class
.getSimpleName();
// FIELDS
public static final String CHAR_ID = JDBCCharacterDAO.CHAR_ID;
public static final String CHAR_ID_FRIEND = JDBCCharacterDAO.CHAR_ID
+ "_friend";
/**
* @param database
* the database service
* @param idProvider
* the frind id provider
* @param charIdProvider
* the character id provider
*/
@Inject
public OrientDBCharacterFriendDAO(DatabaseService database,
final FriendIDProvider idProvider,
CharacterIDProvider charIdProvider) {
super(database);
this.idProvider = idProvider;
this.charIdProvider = charIdProvider;
}
/**
* The {@link Mapper} for {@link FriendID}
*/
private final Mapper<FriendID> idMapper = new Mapper<FriendID>() {
@Override
public FriendID map(ODocument document) throws SQLException {
final CharacterID characterId = charIdProvider
.resolveID((Integer) document.field(CHAR_ID));
final CharacterID friendId = charIdProvider
.resolveID((Integer) document.field(CHAR_ID_FRIEND));
return idProvider.createID(characterId, friendId);
}
};
/**
* The {@link Mapper} for {@link CharacterFriend}
*/
private final Mapper<CharacterFriend> mapper = new CachedMapper<CharacterFriend, FriendID>(
database, idMapper) {
@Override
protected CharacterFriend map(FriendID id, ODocument document)
throws SQLException {
return new CharacterFriend(id);
}
};
@Override
public CharacterFriend select(final FriendID id) {
return database.query(new SelectSingleQuery<CharacterFriend>() {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database) {
return new ONativeSynchQuery<OQueryContextNative>(database,
CLASS_NAME, new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative criteria) {
return criteria.field(CHAR_ID).eq(id.getID1().getID())
.field(CHAR_ID_FRIEND).eq(id.getID2().getID())
.go();
};
};
}
@Override
protected Mapper<CharacterFriend> mapper() {
return mapper;
}
});
}
@Override
public void load(final L2Character character) {
final List<CharacterFriend> list = database
.query(new SelectListQuery<CharacterFriend>() {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database) {
return new ONativeSynchQuery<OQueryContextNative>(
database, CLASS_NAME, new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative criteria) {
return criteria.field(CHAR_ID)
.eq(character.getID().getID()).go();
};
};
}
@Override
protected Mapper<CharacterFriend> mapper() {
return mapper;
}
});
character.getFriendList().load(list);
}
@Override
public List<FriendID> selectIDs() {
return database.query(new SelectListQuery<FriendID>() {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database) {
return new ONativeSynchQuery<OQueryContextNative>(database,
CLASS_NAME, new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative criteria) {
return true;
};
};
}
@Override
protected Mapper<FriendID> mapper() {
return idMapper;
}
});
}
@Override
public int insertObjects(CharacterFriend... friends) {
return database.query(new InsertUpdateQuery<CharacterFriend>(friends) {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database, CharacterFriend object) {
return null;
}
@Override
protected ODocument update(ODocument document,
CharacterFriend object) throws SQLException {
return null;
}
@Override
protected ODocument insert(ODocument document,
CharacterFriend friend) throws SQLException {
document.field(CHAR_ID, friend.getCharacterID());
document.field(CHAR_ID_FRIEND, friend.getFriendID());
return document;
}
});
}
@Override
public int updateObjects(CharacterFriend... friends) {
// it is not possible update friend objects, because they are only a ID
// pair and IDs are immutable
return 0;
}
@Override
public int deleteObjects(CharacterFriend... friends) {
return database.query(new InsertUpdateQuery<CharacterFriend>(friends) {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database, final CharacterFriend friend) {
return new ONativeSynchQuery<OQueryContextNative>(database,
CLASS_NAME, new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative criteria) {
return criteria.field(CHAR_ID)
.eq(friend.getCharacterID().getID()).and()
.field(CHAR_ID_FRIEND)
.eq(friend.getFriendID().getID()).go();
};
};
}
@Override
protected ODocument update(ODocument document,
CharacterFriend object) throws SQLException {
document.delete();
return null;
}
@Override
protected ODocument insert(ODocument document,
CharacterFriend friend) throws SQLException {
return null;
}
});
}
@Override
public boolean save(final CharacterFriendList friends) {
for (final CharacterFriend friend : friends) {
if (save(friend) == 0)
return false;
}
return true;
}
@Override
public boolean delete(final CharacterFriendList friends) {
for (final CharacterFriend friend : friends) {
if (deleteObjects(friend) == 0)
return false;
}
return true;
}
@Override
protected CharacterFriend[] wrap(Model<?>... objects) {
final CharacterFriend[] array = new CharacterFriend[objects.length];
int i = 0;
for (final Model<?> object : objects) {
array[i++] = (CharacterFriend) object;
}
return array;
}
}

View File

@@ -1,264 +0,0 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.orientdb;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import com.google.inject.Inject;
import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterDAO;
import com.l2jserver.model.dao.ChatMessageDAO;
import com.l2jserver.model.id.ChatMessageID;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.id.object.provider.CharacterIDProvider;
import com.l2jserver.model.id.provider.ChatMessageIDProvider;
import com.l2jserver.model.server.ChatMessage;
import com.l2jserver.service.database.AbstractOrientDatabaseService.CachedMapper;
import com.l2jserver.service.database.AbstractOrientDatabaseService.InsertUpdateQuery;
import com.l2jserver.service.database.AbstractOrientDatabaseService.Mapper;
import com.l2jserver.service.database.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.AbstractOrientDatabaseService.SelectSingleQuery;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.game.chat.ChatMessageType;
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;
/**
* {@link CharacterDAO} implementation for JDBC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBChatMessageDAO extends
AbstractOrientDBDAO<ChatMessage, ChatMessageID> implements
ChatMessageDAO {
/**
* The {@link ChatMessageID} factory
*/
private final ChatMessageIDProvider idFactory;
/**
* The {@link CharacterID} factory
*/
private final CharacterIDProvider charIdFactory;
/**
* Character table name
*/
public static final String CLASS_NAME = ChatMessage.class.getSimpleName();
// FIELDS
public static final String MESSAGE_ID = "message_id";
public static final String TYPE = "type";
public static final String CHANNEL_ID = "channel_id";
public static final String SENDER = "sender";
public static final String DATE = "date";
public static final String MESSAGE = "message";
/**
* @param database
* the database service
* @param idFactory
* the chat message id provider
* @param charIdFactory
* the character id provider
*/
@Inject
public OrientDBChatMessageDAO(DatabaseService database,
ChatMessageIDProvider idFactory,
final CharacterIDProvider charIdFactory) {
super(database);
this.idFactory = idFactory;
this.charIdFactory = charIdFactory;
}
/**
* The {@link Mapper} for {@link ChatMessageID}
*/
private final Mapper<ChatMessageID> idMapper = new Mapper<ChatMessageID>() {
@Override
public ChatMessageID map(ODocument document) throws SQLException {
return idFactory.resolveID((Integer) document.field(MESSAGE_ID));
}
};
/**
* The {@link Mapper} for {@link ChatMessage}
*/
private final Mapper<ChatMessage> mapper = new CachedMapper<ChatMessage, ChatMessageID>(
database, idMapper) {
@Override
protected ChatMessage map(ChatMessageID id, ODocument document)
throws SQLException {
final ChatMessage message = new ChatMessage();
message.setID(id);
message.setType(ChatMessageType.valueOf((String) document
.field(TYPE)));
switch (message.getType()) {
case SHOUT:
message.setTarget(charIdFactory.resolveID((Integer) document
.field(CHANNEL_ID)));
break;
default:
message.setChannelID((Integer) document.field(CHANNEL_ID));
break;
}
message.setSender(charIdFactory.resolveID((Integer) document
.field(SENDER)));
message.setDate((Date) document.field(DATE));
message.setMessage((String) document.field(MESSAGE));
return message;
}
};
@Override
public ChatMessage select(final ChatMessageID id) {
return database.query(new SelectSingleQuery<ChatMessage>() {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database) {
return new ONativeSynchQuery<OQueryContextNative>(database,
CLASS_NAME, new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative criteria) {
return criteria.field(MESSAGE_ID).eq(id.getID()).go();
};
};
}
@Override
protected Mapper<ChatMessage> mapper() {
return mapper;
}
});
}
@Override
public List<ChatMessageID> selectIDs() {
return database.query(new SelectListQuery<ChatMessageID>() {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database) {
return new ONativeSynchQuery<OQueryContextNative>(database,
CLASS_NAME, new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative criteria) {
return true;
};
};
}
@Override
protected Mapper<ChatMessageID> mapper() {
return idMapper;
}
});
}
@Override
public int insertObjects(ChatMessage... messages) {
return database.query(new InsertUpdateQuery<ChatMessage>(messages) {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database, ChatMessage object) {
return null;
}
@Override
protected ODocument update(ODocument document, ChatMessage object)
throws SQLException {
return null;
}
@Override
protected ODocument insert(ODocument document, ChatMessage message)
throws SQLException {
document.field(TYPE, message.getType().name());
switch (message.getType()) {
case SHOUT:
document.field(CHANNEL_ID, message.getTarget().getID());
break;
default:
document.field(CHANNEL_ID, message.getChannelID());
break;
}
document.field(SENDER, message.getTarget().getID());
document.field(DATE, message.getDate());
document.field(MESSAGE, message.getMessage());
return document;
}
});
}
@Override
public int updateObjects(ChatMessage... messages) {
// cannot update chat message logs
return 0;
}
@Override
public int deleteObjects(ChatMessage... messages) {
return database.query(new InsertUpdateQuery<ChatMessage>(messages) {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database, final ChatMessage message) {
return new ONativeSynchQuery<OQueryContextNative>(database,
CLASS_NAME, new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative criteria) {
return criteria.field(MESSAGE_ID).eq(message.getID())
.and().go();
};
};
}
@Override
protected ODocument update(ODocument document, ChatMessage object)
throws SQLException {
document.delete();
return null;
}
@Override
protected ODocument insert(ODocument document, ChatMessage object)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
});
}
@Override
protected ChatMessage[] wrap(Model<?>... objects) {
final ChatMessage[] array = new ChatMessage[objects.length];
int i = 0;
for (final Model<?> object : objects) {
array[i++] = (ChatMessage) object;
}
return array;
}
}

View File

@@ -1,231 +0,0 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.database.orientdb;
import java.sql.SQLException;
import java.util.List;
import com.google.inject.Inject;
import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterDAO;
import com.l2jserver.model.dao.ClanDAO;
import com.l2jserver.model.id.ChatMessageID;
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.world.Clan;
import com.l2jserver.service.database.AbstractOrientDatabaseService.CachedMapper;
import com.l2jserver.service.database.AbstractOrientDatabaseService.InsertUpdateQuery;
import com.l2jserver.service.database.AbstractOrientDatabaseService.Mapper;
import com.l2jserver.service.database.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.AbstractOrientDatabaseService.SelectSingleQuery;
import com.l2jserver.service.database.DatabaseService;
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;
/**
* {@link CharacterDAO} implementation for JDBC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBClanDAO extends AbstractOrientDBDAO<Clan, ClanID>
implements ClanDAO {
/**
* The {@link ChatMessageID} factory
*/
private final ClanIDProvider idFactory;
/**
* The {@link CharacterID} factory
*/
private final CharacterIDProvider charIdFactory;
/**
* Clan table name
*/
public static final String CLASS_NAME = Clan.class.getSimpleName();
// FIELDS
public static final String CLAN_ID = "clan_id";
public static final String CHAR_ID_LEADER = "character_id_leader";
/**
* @param database
* the database service
* @param idFactory
* the chat message id provider
* @param charIdFactory
* the character id provider
*/
@Inject
public OrientDBClanDAO(DatabaseService database, ClanIDProvider idFactory,
final CharacterIDProvider charIdFactory) {
super(database);
this.idFactory = idFactory;
this.charIdFactory = charIdFactory;
}
/**
* The {@link Mapper} for {@link ClanID}
*/
private final Mapper<ClanID> idMapper = new Mapper<ClanID>() {
@Override
public ClanID map(ODocument document) throws SQLException {
return idFactory.resolveID((Integer) document.field(CLAN_ID));
}
};
/**
* The {@link Mapper} for {@link Clan}
*/
private final Mapper<Clan> mapper = new CachedMapper<Clan, ClanID>(
database, idMapper) {
@Override
protected Clan map(ClanID id, ODocument document) throws SQLException {
final Clan clan = new Clan();
clan.setID(id);
clan.setLeaderID(charIdFactory.resolveID((Integer) document
.field(CHAR_ID_LEADER)));
return clan;
}
};
@Override
public Clan select(final ClanID id) {
return database.query(new SelectSingleQuery<Clan>() {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database) {
return new ONativeSynchQuery<OQueryContextNative>(database,
CLASS_NAME, new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative criteria) {
return criteria.field(CLAN_ID).eq(id.getID()).go();
};
};
}
@Override
protected Mapper<Clan> mapper() {
return mapper;
}
});
}
@Override
public List<ClanID> selectIDs() {
return database.query(new SelectListQuery<ClanID>() {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database) {
return new ONativeSynchQuery<OQueryContextNative>(database,
CLASS_NAME, new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative criteria) {
return true;
};
};
}
@Override
protected Mapper<ClanID> mapper() {
return idMapper;
}
});
}
@Override
public int insertObjects(Clan... clans) {
return database.query(new InsertUpdateQuery<Clan>(clans) {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database, Clan object) {
return null;
}
@Override
protected ODocument update(ODocument document, Clan object)
throws SQLException {
return null;
}
@Override
protected ODocument insert(ODocument document, Clan clan)
throws SQLException {
document.field(CLAN_ID, clan.getID().getID());
document.field(CHAR_ID_LEADER, clan.getLeaderID().getID());
return document;
}
});
}
@Override
public int updateObjects(Clan... clans) {
// cannot update chat message logs
return 0;
}
@Override
public int deleteObjects(Clan... clans) {
return database.query(new InsertUpdateQuery<Clan>(clans) {
@Override
protected ONativeSynchQuery<OQueryContextNative> createQuery(
ODatabaseDocumentTx database, final Clan clan) {
return new ONativeSynchQuery<OQueryContextNative>(database,
CLASS_NAME, new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative criteria) {
return criteria.field(CLAN_ID).eq(clan.getID()).go();
};
};
}
@Override
protected ODocument update(ODocument document, Clan clan)
throws SQLException {
document.delete();
return null;
}
@Override
protected ODocument insert(ODocument document, Clan object)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
});
}
@Override
protected Clan[] wrap(Model<?>... objects) {
final Clan[] array = new Clan[objects.length];
int i = 0;
for (final Model<?> object : objects) {
array[i++] = (Clan) object;
}
return array;
}
}

View File

@@ -16,10 +16,10 @@
*/ */
package com.l2jserver.db.dao.mysql5; package com.l2jserver.db.dao.mysql5;
import junit.framework.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Stage; import com.google.inject.Stage;
@@ -30,17 +30,28 @@ import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.ServiceManager; import com.l2jserver.service.ServiceManager;
import com.l2jserver.service.ServiceStartException; import com.l2jserver.service.ServiceStartException;
import com.l2jserver.service.database.DatabaseService; import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.mapper.CharacterFriendMapper;
import com.l2jserver.service.database.mapper.CharacterMapper;
import com.l2jserver.service.database.mapper.CharacterShortcutMapper;
import com.l2jserver.service.game.template.TemplateService; import com.l2jserver.service.game.template.TemplateService;
import com.l2jserver.service.game.world.WorldService; import com.l2jserver.service.game.world.WorldService;
public class MySQL5CharacterDAOTest { public class MySQL5CharacterDAOTest {
private final Injector injector = Guice.createInjector(Stage.PRODUCTION, private final Injector injector = Guice.createInjector(Stage.PRODUCTION,
new GameServerModule()); new GameServerModule(), new AbstractModule() {
@Override
protected void configure() {
bind(CharacterMapper.class);
bind(CharacterFriendMapper.class);
bind(CharacterShortcutMapper.class);
}
});
@Test @Test
public void testCachedLoad() throws ServiceStartException { public void testCachedLoad() throws ServiceStartException {
injector.getInstance(ServiceManager.class).start(TemplateService.class); injector.getInstance(ServiceManager.class).start(TemplateService.class);
injector.getInstance(ServiceManager.class).start(DatabaseService.class); injector.getInstance(ServiceManager.class).start(
DatabaseService.class);
injector.getInstance(ServiceManager.class).start(WorldService.class); injector.getInstance(ServiceManager.class).start(WorldService.class);
final CharacterDAO dao = injector.getInstance(CharacterDAO.class); final CharacterDAO dao = injector.getInstance(CharacterDAO.class);
@@ -49,6 +60,6 @@ public class MySQL5CharacterDAOTest {
final L2Character char2 = dao.select(injector.getInstance( final L2Character char2 = dao.select(injector.getInstance(
CharacterIDProvider.class).resolveID(268437456)); CharacterIDProvider.class).resolveID(268437456));
Assert.assertSame(char1, char2); Assert.assertSame(char1, char2);
} }
} }

View File

@@ -16,48 +16,35 @@
*/ */
package com.l2jserver.service.database; package com.l2jserver.service.database;
import java.sql.ResultSet;
import com.l2jserver.model.Model;
import com.l2jserver.model.id.ID;
import com.l2jserver.service.AbstractService.Depends; import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.cache.CacheService; import com.l2jserver.service.cache.CacheService;
import com.l2jserver.service.configuration.ConfigurationService; import com.l2jserver.service.configuration.ConfigurationService;
import com.l2jserver.service.core.LoggingService; import com.l2jserver.service.core.LoggingService;
import com.l2jserver.service.core.threading.ThreadService; import com.l2jserver.service.core.threading.ThreadService;
import com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService;
/** /**
* This is an implementation of {@link DatabaseService} that provides an layer * This is an implementation of {@link DatabaseService} that provides an layer
* to JDBC. * to JDBC.
* *
* <h1>Internal specification</h1> <h2>The * <h1>Internal specification</h1> <h2>The
* {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Query * {@link com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.Query
* Query} object</h2> * Query} object</h2>
* *
* If you wish to implement a new {@link DataAccessObject} you should try not * 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 * Query} object directly because it only provides low level access to the JDBC
* architecture. Instead, you could use an specialized class, like * 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} , * InsertUpdateQuery} ,
* {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.SelectListQuery * {@link com.l2jserver.service.database.jdbc.AbstractJDBCDatabaseService.SelectListQuery
* SelectListQuery} or * 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 * 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. * Query} class directly.
* *
* <h2>The
* {@link com.l2jserver.service.database.AbstractJDBCDatabaseService.Mapper
* Mapper} object</h2>
*
* 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 <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
@Depends({ LoggingService.class, CacheService.class, @Depends({ LoggingService.class, CacheService.class,

View File

@@ -216,10 +216,5 @@
<url>http://download.java.net/maven/2</url> <url>http://download.java.net/maven/2</url>
<layout>default</layout> <layout>default</layout>
</repository> </repository>
<repository>
<id>orientechnologies-repository</id>
<name>Orient Technologies Maven2 Repository</name>
<url>http://www.orientechnologies.com/listing/m2</url>
</repository>
</repositories> </repositories>
</project> </project>