mirror of
https://github.com/Rogiel/l2jserver2
synced 2025-12-06 07:32:46 +00:00
Add support for OrientDatabaseService
OrientDB is an object database. Data is stored in a pair of key-value and can be retrieved or filtered using any of those keys. Data is stored at 'data/database' and has been added to .gitignore.
This commit is contained in:
1
data/.gitignore
vendored
1
data/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
/cache
|
||||
/pathing.db
|
||||
/database.h2.db
|
||||
/database
|
||||
34
pom.xml
34
pom.xml
@@ -93,9 +93,18 @@
|
||||
<descriptors>
|
||||
<descriptor>src/assembly/distribution-mysql5-bin.xml</descriptor>
|
||||
<descriptor>src/assembly/distribution-h2-bin.xml</descriptor>
|
||||
<descriptor>src/assembly/distribution-orientdb-bin.xml</descriptor>
|
||||
<descriptor>src/assembly/distribution-src.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>assembly</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
@@ -158,22 +167,27 @@
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.16</version>
|
||||
<type>jar</type>
|
||||
<scope>runtime</scope>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.3.155</version>
|
||||
<type>jar</type>
|
||||
<scope>runtime</scope>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-dbcp</groupId>
|
||||
<artifactId>commons-dbcp</artifactId>
|
||||
<version>1.4</version>
|
||||
<type>jar</type>
|
||||
<scope>runtime</scope>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.orientechnologies</groupId>
|
||||
<artifactId>orientdb-core</artifactId>
|
||||
<version>1.0rc5</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- cache -->
|
||||
<dependency>
|
||||
@@ -234,7 +248,6 @@
|
||||
<type>jar</type>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- vfs -->
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
@@ -253,8 +266,13 @@
|
||||
<layout>default</layout>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>EclipseLink Repo</id>
|
||||
<url>http://www.eclipse.org/downloads/download.php?r=1&nf=1&file=/rt/eclipselink/maven.repo</url>
|
||||
<id>orientechnologies-repository</id>
|
||||
<name>Orient Technologies Maven2 Repository</name>
|
||||
<url>http://www.orientechnologies.com/listing/m2</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
<updatePolicy>always</updatePolicy>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
||||
|
||||
@@ -42,11 +42,12 @@
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
<outputDirectory>/libs</outputDirectory>
|
||||
<useProjectArtifact>true</useProjectArtifact>
|
||||
<useProjectArtifact>false</useProjectArtifact>
|
||||
<unpack>false</unpack>
|
||||
<scope>runtime</scope>
|
||||
<excludes>
|
||||
<exclude>mysql:mysql-connector-java</exclude>
|
||||
<exclude>mysql:*</exclude>
|
||||
<exclude>com.orientechnologies:*</exclude>
|
||||
</excludes>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
|
||||
@@ -42,11 +42,12 @@
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
<outputDirectory>/libs</outputDirectory>
|
||||
<useProjectArtifact>true</useProjectArtifact>
|
||||
<useProjectArtifact>false</useProjectArtifact>
|
||||
<unpack>false</unpack>
|
||||
<scope>runtime</scope>
|
||||
<excludes>
|
||||
<exclude>com.h2database:h2</exclude>
|
||||
<exclude>com.h2database:*</exclude>
|
||||
<exclude>com.orientechnologies:*</exclude>
|
||||
</excludes>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
|
||||
51
src/assembly/distribution-orientdb-bin.xml
Normal file
51
src/assembly/distribution-orientdb-bin.xml
Normal file
@@ -0,0 +1,51 @@
|
||||
<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>tar.gz</format> -->
|
||||
<!-- <format>tar.bz2</format> -->
|
||||
<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.h2.*</exclude>
|
||||
</excludes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.basedir}/dist</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<includes>
|
||||
<include>${project.artifactId}-${project.version}.jar</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
<outputDirectory>/libs</outputDirectory>
|
||||
<useProjectArtifact>false</useProjectArtifact>
|
||||
<unpack>false</unpack>
|
||||
<scope>runtime</scope>
|
||||
<excludes>
|
||||
<exclude>mysql:*</exclude>
|
||||
<exclude>com.h2database:*</exclude>
|
||||
<exclude>commons-dbcp:*</exclude>
|
||||
</excludes>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
</assembly>
|
||||
@@ -26,7 +26,7 @@
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
<outputDirectory>/libs</outputDirectory>
|
||||
<useProjectArtifact>true</useProjectArtifact>
|
||||
<useProjectArtifact>false</useProjectArtifact>
|
||||
<unpack>false</unpack>
|
||||
<scope>runtime</scope>
|
||||
</dependencySet>
|
||||
|
||||
@@ -0,0 +1,726 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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.
|
||||
*
|
||||
* l2jserver 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 l2jserver. 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.Guice;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import com.l2jserver.model.Model;
|
||||
import com.l2jserver.model.Model.ObjectDesire;
|
||||
import com.l2jserver.model.dao.CharacterDAO;
|
||||
import com.l2jserver.model.dao.ClanDAO;
|
||||
import com.l2jserver.model.dao.ItemDAO;
|
||||
import com.l2jserver.model.dao.NPCDAO;
|
||||
import com.l2jserver.model.dao.PetDAO;
|
||||
import com.l2jserver.model.id.ID;
|
||||
import com.l2jserver.model.id.object.allocator.IDAllocator;
|
||||
import com.l2jserver.model.world.Clan;
|
||||
import com.l2jserver.model.world.Item;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.model.world.NPC;
|
||||
import com.l2jserver.model.world.Pet;
|
||||
import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.AbstractService.Depends;
|
||||
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.ProxyConfigurationService.ConfigurationPropertiesKey;
|
||||
import com.l2jserver.service.configuration.XMLConfigurationService.ConfigurationXPath;
|
||||
import com.l2jserver.service.core.LoggingService;
|
||||
import com.l2jserver.service.core.threading.ScheduledAsyncFuture;
|
||||
import com.l2jserver.service.core.threading.ThreadService;
|
||||
import com.l2jserver.service.game.template.TemplateService;
|
||||
import com.l2jserver.util.ArrayIterator;
|
||||
import com.l2jserver.util.ClassUtils;
|
||||
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.OQueryContextNativeSchema;
|
||||
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>
|
||||
*/
|
||||
@Depends({ LoggingService.class, CacheService.class,
|
||||
ConfigurationService.class, TemplateService.class, ThreadService.class })
|
||||
public class OrientDatabaseService extends AbstractService implements
|
||||
DatabaseService {
|
||||
/**
|
||||
* The configuration object
|
||||
*/
|
||||
private final OrientDatabaseConfiguration config;
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private final Logger log = LoggerFactory
|
||||
.getLogger(OrientDatabaseService.class);
|
||||
|
||||
/**
|
||||
* The Google Guice {@link Injector}. It is used to get DAO instances.
|
||||
*/
|
||||
private final Injector injector;
|
||||
|
||||
/**
|
||||
* The cache service
|
||||
*/
|
||||
private final CacheService cacheService;
|
||||
/**
|
||||
* The thread service
|
||||
*/
|
||||
private final ThreadService threadService;
|
||||
|
||||
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 OrientDatabaseService}.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface OrientDatabaseConfiguration extends DatabaseConfiguration {
|
||||
/**
|
||||
* @return the orientdb url
|
||||
*/
|
||||
@ConfigurationPropertyGetter(defaultValue = "file:data/database")
|
||||
@ConfigurationPropertiesKey("orientdb.url")
|
||||
@ConfigurationXPath("/configuration/services/database/orientdb/url")
|
||||
String getUrl();
|
||||
|
||||
/**
|
||||
* @param url
|
||||
* the new orientdb url
|
||||
*/
|
||||
@ConfigurationPropertySetter
|
||||
@ConfigurationPropertiesKey("orientdb.url")
|
||||
@ConfigurationXPath("/configuration/services/database/orientdb/url")
|
||||
void setUrl(String url);
|
||||
|
||||
/**
|
||||
* @return the orientdb database username
|
||||
*/
|
||||
@ConfigurationPropertyGetter(defaultValue = "l2j")
|
||||
@ConfigurationPropertiesKey("orientdb.username")
|
||||
@ConfigurationXPath("/configuration/services/database/orientdb/username")
|
||||
String getUsername();
|
||||
|
||||
/**
|
||||
* @param username
|
||||
* the orientdb database username
|
||||
*/
|
||||
@ConfigurationPropertySetter
|
||||
@ConfigurationPropertiesKey("orientdb.username")
|
||||
@ConfigurationXPath("/configuration/services/database/orientdb/username")
|
||||
void setUsername(String username);
|
||||
|
||||
/**
|
||||
* @return the orientdb database password
|
||||
*/
|
||||
@ConfigurationPropertyGetter(defaultValue = "changeme")
|
||||
@ConfigurationPropertiesKey("orientdb.password")
|
||||
@ConfigurationXPath("/configuration/services/database/orientdb/password")
|
||||
String getPassword();
|
||||
|
||||
/**
|
||||
* @param password
|
||||
* the jdbc database password
|
||||
*/
|
||||
@ConfigurationPropertySetter
|
||||
@ConfigurationPropertiesKey("jdbc.password")
|
||||
@ConfigurationXPath("/configuration/services/database/jdbc/password")
|
||||
void setPassword(String password);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configService
|
||||
* the configuration service
|
||||
* @param injector
|
||||
* the {@link Guice} {@link Injector}
|
||||
* @param cacheService
|
||||
* the cache service
|
||||
* @param threadService
|
||||
* the thread service
|
||||
*/
|
||||
@Inject
|
||||
public OrientDatabaseService(ConfigurationService configService,
|
||||
Injector injector, CacheService cacheService,
|
||||
ThreadService threadService) {
|
||||
config = configService.get(OrientDatabaseConfiguration.class);
|
||||
this.injector = injector;
|
||||
this.cacheService = cacheService;
|
||||
this.threadService = threadService;
|
||||
}
|
||||
|
||||
@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 = getDAO(object
|
||||
.getClass());
|
||||
if (dao.save(object)) {
|
||||
objects++;
|
||||
}
|
||||
}
|
||||
log.info(
|
||||
"{} objects have been saved by the auto save task",
|
||||
objects);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public <M extends Model<I>, I extends ID<M>> DataAccessObject<M, I> getDAO(
|
||||
Class<M> model) {
|
||||
if (ClassUtils.isSubclass(model, L2Character.class)) {
|
||||
return (DataAccessObject) injector.getInstance(CharacterDAO.class);
|
||||
} else if (ClassUtils.isSubclass(model, Clan.class)) {
|
||||
return (DataAccessObject) injector.getInstance(ClanDAO.class);
|
||||
} else if (ClassUtils.isSubclass(model, Item.class)) {
|
||||
return (DataAccessObject) injector.getInstance(ItemDAO.class);
|
||||
} else if (ClassUtils.isSubclass(model, NPC.class)) {
|
||||
return (DataAccessObject) injector.getInstance(NPCDAO.class);
|
||||
} else if (ClassUtils.isSubclass(model, Pet.class)) {
|
||||
return (DataAccessObject) injector.getInstance(PetDAO.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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<ODocument, OQueryContextNativeSchema<ODocument>> 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<ODocument, OQueryContextNativeSchema<ODocument>> 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<ODocument, OQueryContextNativeSchema<ODocument>> 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<ODocument, OQueryContextNativeSchema<ODocument>> 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 OrientDatabaseService 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(OrientDatabaseService 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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.
|
||||
*
|
||||
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.service.database.orientdb;
|
||||
|
||||
import com.l2jserver.model.Model;
|
||||
import com.l2jserver.model.id.ID;
|
||||
import com.l2jserver.service.database.AbstractDAO;
|
||||
import com.l2jserver.service.database.DatabaseService;
|
||||
import com.l2jserver.service.database.OrientDatabaseService;
|
||||
|
||||
/**
|
||||
* @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<?>>
|
||||
extends AbstractDAO<T, I> {
|
||||
protected final OrientDatabaseService database;
|
||||
|
||||
/**
|
||||
* @param database
|
||||
* the database instance
|
||||
*/
|
||||
protected AbstractOrientDBDAO(DatabaseService database) {
|
||||
super(database);
|
||||
this.database = (OrientDatabaseService) database;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver 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.
|
||||
*
|
||||
* l2jserver 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 l2jserver. 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.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.CharacterTemplate;
|
||||
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.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.DatabaseService;
|
||||
import com.l2jserver.service.database.OrientDatabaseService.CachedMapper;
|
||||
import com.l2jserver.service.database.OrientDatabaseService.InsertUpdateQuery;
|
||||
import com.l2jserver.service.database.OrientDatabaseService.Mapper;
|
||||
import com.l2jserver.service.database.OrientDatabaseService.SelectListQuery;
|
||||
import com.l2jserver.service.database.OrientDatabaseService.SelectSingleQuery;
|
||||
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.OQueryContextNativeSchema;
|
||||
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<ODocument, OQueryContextNativeSchema<ODocument>> createQuery(
|
||||
ODatabaseDocumentTx database) {
|
||||
return new ONativeSynchQuery<ODocument, OQueryContextNativeSchema<ODocument>>(
|
||||
database, CLASS_NAME,
|
||||
new OQueryContextNativeSchema<ODocument>()) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean filter(
|
||||
OQueryContextNativeSchema<ODocument> 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<ODocument, OQueryContextNativeSchema<ODocument>> createQuery(
|
||||
ODatabaseDocumentTx database) {
|
||||
return new ONativeSynchQuery<ODocument, OQueryContextNativeSchema<ODocument>>(
|
||||
database, CLASS_NAME,
|
||||
new OQueryContextNativeSchema<ODocument>()) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean filter(
|
||||
OQueryContextNativeSchema<ODocument> criteria) {
|
||||
return true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Mapper<CharacterID> mapper() {
|
||||
return idMapper;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean insert(L2Character object) {
|
||||
return database.query(new InsertUpdateQuery<L2Character>(object) {
|
||||
@Override
|
||||
protected ONativeSynchQuery<ODocument, OQueryContextNativeSchema<ODocument>> 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;
|
||||
}
|
||||
}) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(final L2Character character) {
|
||||
return database.query(new InsertUpdateQuery<L2Character>(character) {
|
||||
@Override
|
||||
protected ONativeSynchQuery<ODocument, OQueryContextNativeSchema<ODocument>> createQuery(
|
||||
ODatabaseDocumentTx database, final L2Character character) {
|
||||
return new ONativeSynchQuery<ODocument, OQueryContextNativeSchema<ODocument>>(
|
||||
database, CLASS_NAME,
|
||||
new OQueryContextNativeSchema<ODocument>()) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean filter(
|
||||
OQueryContextNativeSchema<ODocument> 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;
|
||||
}
|
||||
}) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(L2Character object) {
|
||||
return database.query(new InsertUpdateQuery<L2Character>(object) {
|
||||
@Override
|
||||
protected ONativeSynchQuery<ODocument, OQueryContextNativeSchema<ODocument>> createQuery(
|
||||
ODatabaseDocumentTx database, final L2Character character) {
|
||||
return new ONativeSynchQuery<ODocument, OQueryContextNativeSchema<ODocument>>(
|
||||
database, CLASS_NAME,
|
||||
new OQueryContextNativeSchema<ODocument>()) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean filter(
|
||||
OQueryContextNativeSchema<ODocument> 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;
|
||||
}
|
||||
}) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(Clan clan) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Character selectByName(final String name) {
|
||||
return database.query(new SelectSingleQuery<L2Character>() {
|
||||
@Override
|
||||
protected ONativeSynchQuery<ODocument, OQueryContextNativeSchema<ODocument>> createQuery(
|
||||
ODatabaseDocumentTx database) {
|
||||
return new ONativeSynchQuery<ODocument, OQueryContextNativeSchema<ODocument>>(
|
||||
database, CLASS_NAME,
|
||||
new OQueryContextNativeSchema<ODocument>()) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean filter(
|
||||
OQueryContextNativeSchema<ODocument> 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<ODocument, OQueryContextNativeSchema<ODocument>> createQuery(
|
||||
ODatabaseDocumentTx database) {
|
||||
return new ONativeSynchQuery<ODocument, OQueryContextNativeSchema<ODocument>>(
|
||||
database, CLASS_NAME,
|
||||
new OQueryContextNativeSchema<ODocument>()) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean filter(
|
||||
OQueryContextNativeSchema<ODocument> criteria) {
|
||||
return criteria.field(ACCOUNT_ID).eq(account.getID()).go();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Mapper<L2Character> mapper() {
|
||||
return mapper;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user