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

Implements OrientDB as internal plug-and-play database

This commit is contained in:
2011-12-25 21:13:00 -02:00
parent a55a1d55f6
commit 1a4a4b0fcf
57 changed files with 43925 additions and 41789 deletions

View File

@@ -124,6 +124,16 @@
<type>jar</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orient-commons</artifactId>
<version>1.0rc7</version>
</dependency>
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-core</artifactId>
<version>1.0rc7</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>

View File

@@ -16,12 +16,16 @@
*/
package com.l2jserver.service.database;
import java.io.IOException;
import java.nio.file.Path;
import com.l2jserver.model.Model;
import com.l2jserver.model.id.ID;
import com.l2jserver.service.Service;
import com.l2jserver.service.ServiceConfiguration;
import com.l2jserver.service.configuration.Configuration;
import com.l2jserver.service.core.threading.AsyncFuture;
import com.mysema.query.sql.RelationalPathBase;
/**
* This service provides access to an database implementation. Each
@@ -101,6 +105,26 @@ public interface DatabaseService extends Service {
int perform();
}
/**
* Imports an static data file into the database. File must be an CSV file
* with the first row as column names.
*
* @param <M>
* the model type
* @param <T>
* the table type
*
* @param path
* the path
* @param entity
* the table
* @throws IOException
* if any error occur while reading or parsing the file
*/
<M extends Model<?>, T extends RelationalPathBase<?>> void importData(
Path path, T entity)
throws IOException;
/**
* Checks for the cached version of the object
*

View File

@@ -0,0 +1,59 @@
/*
* 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.util.Map;
import com.l2jserver.service.database.dao.DatabaseRow;
import com.l2jserver.util.transformer.Transformer;
import com.l2jserver.util.transformer.TransformerFactory;
import com.mysema.query.types.Path;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class StaticDatabaseRow implements DatabaseRow {
/**
* The static data
*/
private final Map<String, String> data;
/**
* @param data
* the data
*/
public StaticDatabaseRow(Map<String, String> data) {
this.data = data;
}
@Override
public <T> T get(Path<T> path) {
final String value = data.get(path.getMetadata().getExpression()
.toString());
@SuppressWarnings("unchecked")
Transformer<T> transformer = (Transformer<T>) TransformerFactory
.getTransfromer(path.getType());
return transformer.untransform(path.getType(), value);
}
@Override
public <T> boolean isNull(Path<T> path) {
// TODO Auto-generated method stub
return false;
}
}

View File

@@ -14,15 +14,15 @@
* 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.sql.ddl;
package com.l2jserver.service.database.ddl;
import java.util.List;
import com.l2jserver.service.database.sql.ddl.struct.Column;
import com.l2jserver.service.database.sql.ddl.struct.Column.ColumnType;
import com.l2jserver.service.database.sql.ddl.struct.ForeignKey;
import com.l2jserver.service.database.sql.ddl.struct.PrimaryKey;
import com.l2jserver.service.database.sql.ddl.struct.Table;
import com.l2jserver.service.database.ddl.struct.Column;
import com.l2jserver.service.database.ddl.struct.ForeignKey;
import com.l2jserver.service.database.ddl.struct.PrimaryKey;
import com.l2jserver.service.database.ddl.struct.Table;
import com.l2jserver.service.database.ddl.struct.Column.ColumnType;
import com.l2jserver.util.factory.CollectionFactory;
/**

View File

@@ -14,9 +14,9 @@
* 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.sql.ddl;
package com.l2jserver.service.database.ddl;
import com.l2jserver.service.database.sql.ddl.struct.Column.ColumnType;
import com.l2jserver.service.database.ddl.struct.Column.ColumnType;
import com.mysema.query.sql.SQLTemplates;
/**

View File

@@ -14,7 +14,7 @@
* 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.sql.ddl;
package com.l2jserver.service.database.ddl;
import java.lang.reflect.Field;
import java.sql.Connection;
@@ -27,15 +27,15 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnAutoIncrement;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnDefault;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.l2jserver.service.database.sql.ddl.struct.Column;
import com.l2jserver.service.database.sql.ddl.struct.Column.ColumnType;
import com.l2jserver.service.database.sql.ddl.struct.ForeignKey;
import com.l2jserver.service.database.sql.ddl.struct.PrimaryKey;
import com.l2jserver.service.database.sql.ddl.struct.Table;
import com.l2jserver.service.database.ddl.annotation.ColumnAutoIncrement;
import com.l2jserver.service.database.ddl.annotation.ColumnDefault;
import com.l2jserver.service.database.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.l2jserver.service.database.ddl.struct.Column;
import com.l2jserver.service.database.ddl.struct.ForeignKey;
import com.l2jserver.service.database.ddl.struct.PrimaryKey;
import com.l2jserver.service.database.ddl.struct.Table;
import com.l2jserver.service.database.ddl.struct.Column.ColumnType;
import com.l2jserver.util.ClassUtils;
import com.l2jserver.util.factory.CollectionFactory;
import com.mysema.query.sql.RelationalPathBase;

View File

@@ -14,7 +14,7 @@
* 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.sql.ddl.annotation;
package com.l2jserver.service.database.ddl.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;

View File

@@ -14,7 +14,7 @@
* 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.sql.ddl.annotation;
package com.l2jserver.service.database.ddl.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;

View File

@@ -14,7 +14,7 @@
* 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.sql.ddl.annotation;
package com.l2jserver.service.database.ddl.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;

View File

@@ -14,7 +14,7 @@
* 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.sql.ddl.annotation;
package com.l2jserver.service.database.ddl.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;

View File

@@ -14,7 +14,7 @@
* 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.sql.ddl.struct;
package com.l2jserver.service.database.ddl.struct;
import java.util.List;

View File

@@ -14,7 +14,7 @@
* 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.sql.ddl.struct;
package com.l2jserver.service.database.ddl.struct;
import java.util.Collections;
import java.util.List;

View File

@@ -14,7 +14,7 @@
* 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.sql.ddl.struct;
package com.l2jserver.service.database.ddl.struct;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>

View File

@@ -14,7 +14,7 @@
* 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.sql.ddl.struct;
package com.l2jserver.service.database.ddl.struct;
import java.util.Collection;
import java.util.Collections;

View File

@@ -14,10 +14,10 @@
* 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.sql.ddl.template;
package com.l2jserver.service.database.ddl.template;
import com.l2jserver.service.database.sql.ddl.QueryTemplate;
import com.l2jserver.service.database.sql.ddl.struct.Column.ColumnType;
import com.l2jserver.service.database.ddl.QueryTemplate;
import com.l2jserver.service.database.ddl.struct.Column.ColumnType;
import com.mysema.query.QueryMetadata;
import com.mysema.query.QueryModifiers;
import com.mysema.query.sql.support.SerializationContext;

View File

@@ -14,10 +14,10 @@
* 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.sql.ddl.template;
package com.l2jserver.service.database.ddl.template;
import com.l2jserver.service.database.sql.ddl.QueryTemplate;
import com.l2jserver.service.database.sql.ddl.struct.Column.ColumnType;
import com.l2jserver.service.database.ddl.QueryTemplate;
import com.l2jserver.service.database.ddl.struct.Column.ColumnType;
import com.mysema.query.types.Ops;
/**

View File

@@ -14,12 +14,12 @@
* 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.sql.ddl.template;
package com.l2jserver.service.database.ddl.template;
import java.math.BigDecimal;
import com.l2jserver.service.database.sql.ddl.QueryTemplate;
import com.l2jserver.service.database.sql.ddl.struct.Column.ColumnType;
import com.l2jserver.service.database.ddl.QueryTemplate;
import com.l2jserver.service.database.ddl.struct.Column.ColumnType;
import com.mysema.query.types.Ops;
/**

View File

@@ -0,0 +1,51 @@
/*
* 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 com.google.inject.Inject;
import com.l2jserver.model.Model;
import com.l2jserver.model.id.ID;
import com.l2jserver.service.database.AbstractDAO;
import com.l2jserver.service.database.DatabaseService;
/**
* {@link AbstractDAO} for OrientDB DAO implementation
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <T>
* the object for the DAO
* @param <I>
* the object ID type
*/
public abstract class AbstractOrientDBDAO<T extends Model<?>, I extends ID<?>>
extends AbstractDAO<T, I> {
/**
* The JDBC Database Service
*/
protected final AbstractOrientDatabaseService database;
/**
* @param database
* the database service
*/
@Inject
protected AbstractOrientDBDAO(DatabaseService database) {
super(database);
this.database = (AbstractOrientDatabaseService) database;
}
}

View File

@@ -0,0 +1,795 @@
/*
* 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.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.StringUtils;
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.DatabaseService;
import com.l2jserver.service.database.dao.DatabaseRow;
import com.l2jserver.service.database.dao.InsertMapper;
import com.l2jserver.service.database.dao.SelectMapper;
import com.l2jserver.service.database.dao.UpdateMapper;
import com.l2jserver.util.factory.CollectionFactory;
import com.mysema.query.sql.ForeignKey;
import com.mysema.query.sql.RelationalPathBase;
import com.mysema.query.types.Path;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentPool;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.metadata.schema.OClass.INDEX_TYPE;
import com.orientechnologies.orient.core.metadata.schema.OProperty;
import com.orientechnologies.orient.core.metadata.schema.OSchema;
import com.orientechnologies.orient.core.metadata.schema.OType;
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 OrientDB Document Database.
*
* <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 SelectMapper} object</h2>
*
* The {@link SelectMapper} object maps an OrientDB {@link ODocument} into an
* Java {@link Object}.
*
* @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;
/**
* 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 = "local: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 = "admin")
@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 = "admin")
@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 {
ODatabaseDocumentTx database;
try {
database = ODatabaseDocumentPool.global().acquire(config.getUrl(),
config.getUsername(), config.getPassword());
} catch (Exception e) {
database = new ODatabaseDocumentTx(config.getUrl());
if (!database.exists()) {
database.create();
}
}
ensureDatabaseSchema();
database.close();
// 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");
final ODatabaseDocumentTx database = ODatabaseDocumentPool.global()
.acquire(config.getUrl(), config.getUsername(),
config.getPassword());
log.debug("Executing query {} with {}", query, database);
try {
return query.query(database, this);
} finally {
database.commit();
}
}
@Override
public <M extends Model<?>, T extends RelationalPathBase<?>> void importData(
java.nio.file.Path path, T entity) throws IOException {
final ODatabaseDocumentTx database = ODatabaseDocumentPool.global()
.acquire(config.getUrl(), config.getUsername(),
config.getPassword());
log.info("Importing {} to {}", path, entity);
BufferedReader reader = Files.newBufferedReader(path,
Charset.defaultCharset());
final String header[] = reader.readLine().split(",");
String line;
while ((line = reader.readLine()) != null) {
final String data[] = line.split(",");
final ODocument document = new ODocument(database,
entity.getTableName());
for (int i = 0; i < data.length; i++) {
document.field(header[i], data[i]);
}
database.save(document);
}
}
/**
* Makes sure the database schema is up-to-date with the external database
*/
protected abstract void ensureDatabaseSchema();
/**
* @param table
* the {@link RelationalPathBase} table
* @return true if a new schema was created
*/
protected boolean createSchema(RelationalPathBase<?> table) {
final ODatabaseDocumentTx database = ODatabaseDocumentPool.global()
.acquire(config.getUrl(), config.getUsername(),
config.getPassword());
boolean newSchema = false;
try {
final OSchema schemas = database.getMetadata().getSchema();
OClass schema = schemas.getClass(table.getTableName());
if (schema == null) {
schema = schemas.createClass(table.getTableName());
newSchema = true;
}
for (final Path<?> path : table.all()) {
final String name = path.getMetadata().getExpression()
.toString();
OProperty property = schema.getProperty(name);
if (property == null)
property = schema.createProperty(
path.getMetadata().getExpression().toString(),
(path.getType().isEnum() ? OType.STRING : OType
.getTypeByClass(path.getType())));
if (path.getType().isEnum()) {
property.setType(OType.STRING);
} else {
property.setType(OType.getTypeByClass(path.getType()));
}
}
for (final ForeignKey<?> fk : table.getForeignKeys()) {
final String[] columns = new String[fk.getLocalColumns().size()];
int i = 0;
for (final Path<?> keyPath : fk.getLocalColumns()) {
columns[i++] = keyPath.getMetadata().getExpression()
.toString();
}
schema.createIndex(StringUtils.join(columns, "-"),
INDEX_TYPE.NOTUNIQUE, columns);
}
final String[] pkColumns = new String[table.getPrimaryKey()
.getLocalColumns().size()];
int i = 0;
for (final Path<?> keyPath : table.getPrimaryKey()
.getLocalColumns()) {
pkColumns[i++] = keyPath.getMetadata().getExpression()
.toString();
}
schema.createIndex("PRIMARY", INDEX_TYPE.UNIQUE, pkColumns);
schemas.save();
} finally {
database.close();
}
return newSchema;
}
@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;
ODatabaseDocumentPool.global().close();
}
/**
* 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 instance
* @param service
* the database service instance
* @return the query return value
*/
R query(ODatabaseDocumentTx database, DatabaseService service);
}
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);
}
}
}
protected String name(Path<?> path) {
return path.getMetadata().getExpression().toString();
}
}
public static class InsertQuery<O, RI, I extends ID<? super RI>, E extends RelationalPathBase<?>>
extends AbstractQuery<Integer> {
private final InsertMapper<O, RI, I, E> mapper;
private final Iterator<O> iterator;
@SuppressWarnings("unused")
// FIXME implement id generation
private final Path<RI> primaryKey;
protected final E e;
/**
* @param entity
* the entity type
* @param mapper
* the insert mapper
* @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, InsertMapper<O, RI, I, E> mapper,
Path<RI> primaryKey, Iterator<O> iterator) {
this.iterator = iterator;
this.mapper = mapper;
this.e = entity;
this.primaryKey = primaryKey;
}
/**
* @param entity
* the entity type
* @param mapper
* the insert mapper
* @param iterator
* the objects to be inserted
*/
public InsertQuery(E entity, InsertMapper<O, RI, I, E> mapper,
Iterator<O> iterator) {
this(entity, mapper, null, iterator);
}
/**
* @param entity
* the entity type
* @param mapper
* the insert mapper
* @param objects
* the objects to be inserted
*/
@SafeVarargs
public InsertQuery(E entity, InsertMapper<O, RI, I, E> mapper,
O... objects) {
this(entity, mapper, null, Iterators.forArray(objects));
}
/**
* @param entity
* the entity type
* @param mapper
* the insert mapper
* @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, InsertMapper<O, RI, I, E> mapper,
Path<RI> primaryKey, O... objects) {
this(entity, mapper, primaryKey, Iterators.forArray(objects));
}
@Override
public final Integer query(ODatabaseDocumentTx database,
DatabaseService service) {
int rows = 0;
final DocumentDatabaseRow row = new DocumentDatabaseRow();
while (iterator.hasNext()) {
final O object = iterator.next();
row.setDocument(new ODocument(database, e.getTableName()));
mapper.insert(e, object, row);
// TODO generate ids
row.getDocument().save();
rows++;
updateDesire(object, ObjectDesire.INSERT);
}
return rows;
}
}
public static abstract class UpdateQuery<O, E extends RelationalPathBase<?>>
extends AbstractQuery<Integer> {
private final UpdateMapper<O, E> mapper;
private final Iterator<O> iterator;
protected final E e;
/**
* @param entity
* the entity type
* @param mapper
* the update mapper
* @param iterator
* the objects to be inserted
*/
public UpdateQuery(E entity, UpdateMapper<O, E> mapper,
Iterator<O> iterator) {
this.iterator = iterator;
this.mapper = mapper;
this.e = entity;
}
/**
* @param entity
* the entity type
* @param mapper
* the update mapper
* @param objects
* the objects to be inserted
*/
@SafeVarargs
public UpdateQuery(E entity, UpdateMapper<O, E> mapper, O... objects) {
this(entity, mapper, Iterators.forArray(objects));
}
@Override
public final Integer query(ODatabaseDocumentTx database,
DatabaseService service) {
int rows = 0;
final DocumentDatabaseRow row = new DocumentDatabaseRow();
while (iterator.hasNext()) {
final O object = iterator.next();
List<ODocument> documents = database
.query(new ONativeSynchQuery<OQueryContextNative>(
database, e.getTableName(),
new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative record) {
return query(record, object).go();
};
});
if (documents.size() < 1)
continue;
row.setDocument(documents.get(0));
mapper.update(e, object, row);
row.getDocument().save();
rows++;
updateDesire(object, ObjectDesire.UPDATE);
}
return rows;
}
protected abstract OQueryContextNative query(
OQueryContextNative record, 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(ODatabaseDocumentTx database,
DatabaseService service) {
int rows = 0;
while (iterator.hasNext()) {
final O object = iterator.next();
List<ODocument> documents = database
.query(new ONativeSynchQuery<OQueryContextNative>(
database, e.getTableName(),
new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative record) {
return query(record, object).go();
};
});
for (final ODocument document : documents) {
document.delete();
rows++;
}
updateDesire(object, ObjectDesire.DELETE);
}
return rows;
}
protected abstract OQueryContextNative query(
OQueryContextNative record, O o);
}
public static abstract class AbstractSelectQuery<R, O, RI, I extends ID<? super RI>, E extends RelationalPathBase<RI>>
extends AbstractQuery<R> {
protected final E entity;
protected final SelectMapper<O, RI, I, E> mapper;
/**
* @param entity
* the entity type
* @param mapper
* the object mapper
*/
public AbstractSelectQuery(E entity, SelectMapper<O, RI, I, E> mapper) {
this.entity = entity;
this.mapper = mapper;
}
@Override
public final R query(ODatabaseDocumentTx database,
DatabaseService service) {
List<ODocument> documents = database
.query(new ONativeSynchQuery<OQueryContextNative>(database,
entity.getTableName(), new OQueryContextNative()) {
private static final long serialVersionUID = 1L;
@Override
public boolean filter(OQueryContextNative record) {
record = query(record, entity);
if (record == null)
return true;
return record.go();
};
});
return perform(documents, service);
}
protected abstract OQueryContextNative query(
OQueryContextNative record, E e);
protected abstract R perform(List<ODocument> documents,
DatabaseService service);
@SuppressWarnings("unchecked")
protected O lookupCache(DatabaseRow row, DatabaseService database) {
final I id = mapper.getPrimaryKeyMapper().createID(
(RI) row.get(entity.getPrimaryKey().getLocalColumns()
.get(0)));
if (id != null) {
if (database.hasCachedObject(id))
return (O) database.getCachedObject(id);
}
return null;
}
protected void updateCache(O instance, DatabaseService database) {
if (instance == null)
return;
if (instance instanceof Model)
database.updateCache(((Model<?>) instance).getID(),
(Model<?>) instance);
}
}
public static abstract class SelectSingleQuery<O, RI, I extends ID<? super RI>, E extends RelationalPathBase<RI>>
extends AbstractSelectQuery<O, O, RI, I, E> {
/**
* @param entity
* the entity
* @param mapper
* the mapper
*/
public SelectSingleQuery(E entity, SelectMapper<O, RI, I, E> mapper) {
super(entity, mapper);
}
@Override
protected final O perform(List<ODocument> documents,
DatabaseService service) {
final ODocument document = (!documents.isEmpty() ? documents.get(0)
: null);
if (document == null)
return null;
final DocumentDatabaseRow row = new DocumentDatabaseRow(document);
O object = lookupCache(row, service);
if (object == null) {
object = mapper.select(entity, row);
updateCache(object, service);
if (object instanceof Model) {
((Model<?>) object).setObjectDesire(ObjectDesire.NONE);
}
}
return object;
}
}
public static abstract class SelectListQuery<O, RI, I extends ID<? super RI>, E extends RelationalPathBase<RI>>
extends AbstractSelectQuery<List<O>, O, RI, I, E> {
/**
* @param entity
* the entity
* @param mapper
* the mapper
*/
public SelectListQuery(E entity, SelectMapper<O, RI, I, E> mapper) {
super(entity, mapper);
}
@Override
protected final List<O> perform(List<ODocument> documents,
DatabaseService service) {
final List<O> results = CollectionFactory.newList();
final DocumentDatabaseRow row = new DocumentDatabaseRow();
for (final ODocument document : documents) {
row.setDocument(document);
O object = lookupCache(row, service);
if (object == null) {
object = mapper.select(entity, row);
updateCache(object, service);
if (object instanceof Model) {
((Model<?>) object).setObjectDesire(ObjectDesire.NONE);
}
}
if (object != null)
results.add(object);
}
return results;
}
}
}

View File

@@ -0,0 +1,78 @@
/*
* 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 com.l2jserver.service.database.dao.DatabaseRow;
import com.l2jserver.service.database.dao.WritableDatabaseRow;
import com.mysema.query.types.Path;
import com.orientechnologies.orient.core.record.impl.ODocument;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class DocumentDatabaseRow implements DatabaseRow, WritableDatabaseRow {
private ODocument document;
/**
* @param document
* the orientdb document
*/
public DocumentDatabaseRow(ODocument document) {
this.document = document;
}
public DocumentDatabaseRow() {
}
@Override
public <T> T get(Path<T> path) {
return document.field(path.getMetadata().getExpression().toString(),
path.getType());
}
@Override
public <T> boolean isNull(Path<T> path) {
return get(path) == null;
}
@Override
public <T> WritableDatabaseRow set(Path<T> path, T value) {
document.field(path.getMetadata().getExpression().toString(), value);
return this;
}
@Override
public <T> WritableDatabaseRow setNull(Path<T> path) {
return set(path, null);
}
/**
* @return the orientdb document
*/
public ODocument getDocument() {
return document;
}
/**
* @param document
* the orientdb document to set
*/
public void setDocument(ODocument document) {
this.document = document;
}
}

View File

@@ -25,6 +25,7 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.sql.DataSource;
@@ -64,14 +65,17 @@ import com.l2jserver.service.database.dao.DatabaseRow;
import com.l2jserver.service.database.dao.InsertMapper;
import com.l2jserver.service.database.dao.SelectMapper;
import com.l2jserver.service.database.dao.UpdateMapper;
import com.l2jserver.service.database.sql.ddl.QueryFactory;
import com.l2jserver.service.database.sql.ddl.TableFactory;
import com.l2jserver.service.database.sql.ddl.struct.Table;
import com.l2jserver.service.database.ddl.QueryFactory;
import com.l2jserver.service.database.ddl.TableFactory;
import com.l2jserver.service.database.ddl.struct.Table;
import com.l2jserver.util.factory.CollectionFactory;
import com.mysema.query.sql.AbstractSQLQuery;
import com.mysema.query.sql.RelationalPath;
import com.mysema.query.sql.RelationalPathBase;
import com.mysema.query.sql.SQLQueryFactory;
import com.mysema.query.sql.dml.Mapper;
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;
@@ -442,43 +446,6 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
return create;
}
/**
* Imports an entire SQL file into the database. If the file consists of
* several SQL statements, they will be splitted and executed separated.
*
* @param conn
* the SQL connection
* @param sqlPath
* the path for the SQL file
* @throws IOException
* if any error occur while reading the file
* @throws SQLException
* if any error occur while executing the statements
*/
protected void importSQL(Connection conn, java.nio.file.Path sqlPath)
throws IOException, SQLException {
BufferedReader reader = Files.newBufferedReader(sqlPath,
Charset.defaultCharset());
final StringBuilder builder = new StringBuilder();
String line;
conn.setAutoCommit(false);
try {
while ((line = reader.readLine()) != null) {
builder.append(line).append("\n");
if (line.trim().endsWith(";")) {
executeSQL(conn, builder.substring(0, builder.length() - 2));
builder.setLength(0);
}
}
conn.commit();
} catch (SQLException | IOException e) {
conn.rollback();
throw e;
} finally {
conn.setAutoCommit(true);
}
}
/**
* Executes the SQL code in the databases
*
@@ -503,6 +470,56 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
}
}
@Override
public <M extends Model<?>, T extends RelationalPathBase<?>> void importData(
java.nio.file.Path path, T entity) throws IOException {
Connection conn;
try {
conn = dataSource.getConnection();
} catch (SQLException e) {
return;
}
log.info("Importing {} to {}", path, entity);
try {
BufferedReader reader = Files.newBufferedReader(path,
Charset.defaultCharset());
final String header[] = reader.readLine().split(",");
String line;
while ((line = reader.readLine()) != null) {
final String data[] = line.split(",");
SQLInsertClause insert = engine.createSQLQueryFactory(conn)
.insert(entity);
insert.populate(data, new Mapper<Object[]>() {
@Override
public Map<Path<?>, Object> createMap(
RelationalPath<?> relationalPath, Object[] object) {
final Map<Path<?>, Object> values = CollectionFactory
.newMap();
pathFor: for (final Path<?> path : relationalPath
.getColumns()) {
int i = 0;
for (final String headerName : header) {
if (path.getMetadata().getExpression()
.toString().equals(headerName)) {
values.put(path, object[i]);
continue pathFor;
}
i++;
}
}
return values;
}
});
insert.execute();
}
} finally {
try {
conn.close();
} catch (SQLException e) {
}
}
}
@Override
public int transaction(TransactionExecutor executor) {
Preconditions.checkNotNull(executor, "executor");

View File

@@ -20,7 +20,7 @@ import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;
import com.l2jserver.service.database.sql.ddl.QueryTemplate;
import com.l2jserver.service.database.ddl.QueryTemplate;
import com.mysema.query.sql.AbstractSQLQuery;
import com.mysema.query.sql.SQLQueryFactory;
import com.mysema.query.sql.types.Type;

View File

@@ -24,8 +24,8 @@ import javax.inject.Provider;
import org.apache.derby.jdbc.EmbeddedDriver;
import com.l2jserver.service.database.sql.ddl.QueryTemplate;
import com.l2jserver.service.database.sql.ddl.template.DerbyTemplate;
import com.l2jserver.service.database.ddl.QueryTemplate;
import com.l2jserver.service.database.ddl.template.DerbyTemplate;
import com.mysema.query.sql.AbstractSQLQuery;
import com.mysema.query.sql.Configuration;
import com.mysema.query.sql.SQLQueryFactory;

View File

@@ -23,8 +23,8 @@ import javax.inject.Provider;
import org.h2.Driver;
import com.l2jserver.service.database.sql.ddl.QueryTemplate;
import com.l2jserver.service.database.sql.ddl.template.H2Template;
import com.l2jserver.service.database.ddl.QueryTemplate;
import com.l2jserver.service.database.ddl.template.H2Template;
import com.mysema.query.sql.AbstractSQLQuery;
import com.mysema.query.sql.Configuration;
import com.mysema.query.sql.SQLQueryFactory;

View File

@@ -22,8 +22,8 @@ import java.sql.SQLException;
import javax.inject.Provider;
import com.l2jserver.service.database.sql.ddl.QueryTemplate;
import com.l2jserver.service.database.sql.ddl.template.MySQLTemplate;
import com.l2jserver.service.database.ddl.QueryTemplate;
import com.l2jserver.service.database.ddl.template.MySQLTemplate;
import com.mysema.query.sql.AbstractSQLQuery;
import com.mysema.query.sql.Configuration;
import com.mysema.query.sql.SQLQueryFactory;

View File

@@ -38,7 +38,7 @@ public class ClassTransformer implements Transformer<Class<?>> {
@Override
public Class<?> untransform(Class<? extends Class<?>> type, String value) {
try {
return Class.forName(value);
return Class.forName(value.trim());
} catch (ClassNotFoundException e) {
throw new TransformException(e);
}

View File

@@ -19,12 +19,18 @@
not sure on the usage of any parameter, read the "Configuration" section
in wiki article about DatabaseService. -->
<database>
<orientdb>
<url>local:data/database</url>
<username>admin</username>
<password>admin</password>
</orientdb>
<jdbc>
<!-- Defines the connection URL used by JDBC to connect to the database. -->
<url>jdbc:mysql://localhost/l2jserver2</url>
<!-- The engine used to connect to the database. -->
<engine>com.l2jserver.service.database.sql.MySQLDatabaseEngine</engine>
<engine>com.l2jserver.service.database.sql.MySQLDatabaseEngine
</engine>
<!-- Whether or not the service should try to update and create missing
tables at startup. This should be disabled after the first server start as

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
Data in this folder is only used to first populate the database.
Once it has been populated, it is safe to delete all files within this folder.

View File

@@ -77,6 +77,7 @@ public class L2JGameServerMain {
}
}
}));
} catch (Exception e) {
System.out.println("GameServer could not be started!");
e.printStackTrace();

View File

@@ -89,8 +89,8 @@ public class ServiceModule extends AbstractModule {
bind(CacheService.class).to(SoftCacheService.class)
.in(Scopes.SINGLETON);
bind(DatabaseService.class).to(GameServerJDBCDatabaseService.class).in(
Scopes.SINGLETON);
bind(DatabaseService.class).to(GameServerJDBCDatabaseService.class)
.in(Scopes.SINGLETON);
bind(WorldIDService.class).to(CachedWorldIDService.class).in(
Scopes.SINGLETON);

View File

@@ -112,7 +112,8 @@ public class GameServerJDBCDatabaseService extends AbstractSQLDatabaseService
}
@Override
protected void ensureDatabaseSchema(Connection conn) throws SQLException, IOException {
protected void ensureDatabaseSchema(Connection conn) throws SQLException,
IOException {
updateSchema(conn, QActorSkill.actorSkill);
updateSchema(conn, QCharacter.character);
updateSchema(conn, QCharacterFriend.characterFriend);
@@ -121,7 +122,7 @@ public class GameServerJDBCDatabaseService extends AbstractSQLDatabaseService
updateSchema(conn, QItem.item);
updateSchema(conn, QLogChat.logChat);
if (updateSchema(conn, QNPC.npc)) {
importSQL(conn, vfsService.resolve("data/sql/npc.sql"));
importData(vfsService.resolve("data/static/npc.csv"), QNPC.npc);
}
}
}

View File

@@ -0,0 +1,102 @@
/*
* 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.io.IOException;
import java.nio.file.Paths;
import com.google.inject.Inject;
import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.cache.CacheService;
import com.l2jserver.service.configuration.ConfigurationService;
import com.l2jserver.service.core.LoggingService;
import com.l2jserver.service.core.threading.ThreadService;
import com.l2jserver.service.database.model.QActorSkill;
import com.l2jserver.service.database.model.QCharacter;
import com.l2jserver.service.database.model.QCharacterFriend;
import com.l2jserver.service.database.model.QCharacterShortcut;
import com.l2jserver.service.database.model.QClan;
import com.l2jserver.service.database.model.QItem;
import com.l2jserver.service.database.model.QLogChat;
import com.l2jserver.service.database.model.QNPC;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService;
import com.l2jserver.service.game.template.TemplateService;
/**
* This is an implementation of {@link DatabaseService} that provides an layer
* to OrientDB Object Database.
*
* <h1>Internal specification</h1> <h2>The
* {@link com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.Query
* Query} object</h2>
*
* If you wish to implement a new {@link DataAccessObject} you should try not
* use
* {@link com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.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.orientdb.AbstractOrientDatabaseService.InsertQuery
* InsertUpdateQuery} ,
* {@link com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectListQuery
* SelectListQuery} or
* {@link com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectSingleQuery
* SelectSingleQuery} . If you do need low level access, feel free to use the
* {@link com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.Query
* Query} class directly.
*
* @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);
}
@Override
protected void ensureDatabaseSchema() {
createSchema(QActorSkill.actorSkill);
createSchema(QCharacter.character);
createSchema(QCharacterFriend.characterFriend);
createSchema(QCharacterShortcut.characterShortcut);
createSchema(QClan.clan);
createSchema(QItem.item);
createSchema(QLogChat.logChat);
if (createSchema(QNPC.npc)) {
try {
importData(Paths.get("data/static/npc.csv"), QNPC.npc);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,65 @@
/*
* 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.model.dao.CharacterFriendDAO;
import com.l2jserver.model.dao.CharacterShortcutDAO;
import com.l2jserver.model.dao.ChatMessageDAO;
import com.l2jserver.model.dao.ClanDAO;
import com.l2jserver.model.dao.ItemDAO;
import com.l2jserver.model.dao.NPCDAO;
import com.l2jserver.service.database.dao.orientdb.OrientDBCharacterDAO;
import com.l2jserver.service.database.dao.orientdb.OrientDBCharacterFriendDAO;
import com.l2jserver.service.database.dao.orientdb.OrientDBCharacterShortcutDAO;
import com.l2jserver.service.database.dao.orientdb.OrientDBChatMessageDAO;
import com.l2jserver.service.database.dao.orientdb.OrientDBClanDAO;
import com.l2jserver.service.database.dao.orientdb.OrientDBItemDAO;
import com.l2jserver.service.database.dao.orientdb.OrientDBNPCDAO;
/**
* Google Guice {@link Module} for OrientDB 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(CharacterShortcutDAO.class).to(OrientDBCharacterShortcutDAO.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

@@ -0,0 +1,174 @@
/*
* 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.orientdb;
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.world.Clan;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.mapper.CharacterMapper;
import com.l2jserver.service.database.model.QCharacter;
import com.l2jserver.service.database.orientdb.AbstractOrientDBDAO;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.DeleteQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.InsertQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectSingleQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.UpdateQuery;
import com.orientechnologies.orient.core.query.nativ.OQueryContextNative;
/**
* {@link CharacterDAO} implementation for JDBC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBCharacterDAO extends
AbstractOrientDBDAO<L2Character, CharacterID> implements CharacterDAO {
/**
* The {@link L2Character} mapper
*/
private final CharacterMapper mapper;
/**
* @param database
* the database service
* @param mapper
* the character mapper
*/
@Inject
public OrientDBCharacterDAO(DatabaseService database, CharacterMapper mapper) {
super(database);
this.mapper = mapper;
}
@Override
public L2Character select(final CharacterID id) {
return database
.query(new SelectSingleQuery<L2Character, Integer, CharacterID, QCharacter>(
QCharacter.character, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacter e) {
return record.field(name(entity.characterId)).eq(
id.getID());
}
});
}
@Override
public void load(final Clan clan) {
clan.getMembers()
.load(database
.query(new SelectListQuery<CharacterID, Integer, CharacterID, QCharacter>(
QCharacter.character, mapper
.getIDMapper(QCharacter.character)) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacter e) {
return record.field(name(entity.clanId)).eq(
clan.getID().getID());
}
}));
}
@Override
public L2Character selectByName(final String name) {
return database
.query(new SelectSingleQuery<L2Character, Integer, CharacterID, QCharacter>(
QCharacter.character, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacter e) {
return record.field(name(entity.name)).eq(name);
}
});
}
@Override
public List<L2Character> selectByAccount(final AccountID account) {
return database
.query(new SelectListQuery<L2Character, Integer, CharacterID, QCharacter>(
QCharacter.character, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacter e) {
return record.field(name(entity.accountId)).eq(
account.getID());
}
});
}
@Override
public List<CharacterID> selectIDs() {
return database
.query(new SelectListQuery<CharacterID, Integer, CharacterID, QCharacter>(
QCharacter.character, mapper
.getIDMapper(QCharacter.character)) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacter e) {
return record;
}
});
}
@Override
public int insertObjects(L2Character... characters) {
return database
.query(new InsertQuery<L2Character, Integer, CharacterID, QCharacter>(
QCharacter.character, mapper, characters));
}
@Override
public int updateObjects(L2Character... characters) {
return database.query(new UpdateQuery<L2Character, QCharacter>(
QCharacter.character, mapper, characters) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
L2Character o) {
return record.field(name(e.characterId)).eq(o.getID().getID());
}
});
}
@Override
public int deleteObjects(L2Character... characters) {
return database.query(new DeleteQuery<L2Character, QCharacter>(
QCharacter.character, characters) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
L2Character o) {
return record.field(name(e.characterId)).eq(o.getID().getID());
}
});
}
@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

@@ -0,0 +1,166 @@
/*
* 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.orientdb;
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.world.L2Character;
import com.l2jserver.model.world.character.CharacterFriendList;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.mapper.CharacterFriendMapper;
import com.l2jserver.service.database.model.QCharacterFriend;
import com.l2jserver.service.database.orientdb.AbstractOrientDBDAO;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.DeleteQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.InsertQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectSingleQuery;
import com.orientechnologies.orient.core.query.nativ.OQueryContextNative;
/**
* {@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 CharacterFriend} mapper
*/
private final CharacterFriendMapper mapper;
/**
* @param database
* the database service
* @param mapper
* the character friend mapper
*/
@Inject
public OrientDBCharacterFriendDAO(DatabaseService database,
CharacterFriendMapper mapper) {
super(database);
this.mapper = mapper;
}
@Override
public CharacterFriend select(final FriendID id) {
return database
.query(new SelectSingleQuery<CharacterFriend, FriendID, FriendID, QCharacterFriend>(
QCharacterFriend.characterFriend, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacterFriend e) {
return record.field(name(e.characterId))
.eq(id.getCharacterID().getID())
.field(name(e.characterIdFriend))
.eq(id.getFriendID());
}
});
}
@Override
public void load(final L2Character character) {
final List<CharacterFriend> list = database
.query(new SelectListQuery<CharacterFriend, FriendID, FriendID, QCharacterFriend>(
QCharacterFriend.characterFriend, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacterFriend e) {
return record.field(name(e.characterId)).eq(
character.getID().getID());
}
});
character.getFriendList().load(list);
}
@Override
public List<FriendID> selectIDs() {
return database
.query(new SelectListQuery<FriendID, FriendID, FriendID, QCharacterFriend>(
QCharacterFriend.characterFriend, mapper
.getIDMapper(QCharacterFriend.characterFriend)) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacterFriend e) {
return record;
}
});
}
@Override
public int insertObjects(CharacterFriend... friends) {
return database
.query(new InsertQuery<CharacterFriend, FriendID, FriendID, QCharacterFriend>(
QCharacterFriend.characterFriend, mapper, friends));
}
@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 DeleteQuery<CharacterFriend, QCharacterFriend>(
QCharacterFriend.characterFriend, friends) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, CharacterFriend friend) {
return record.field(name(e.characterId))
.eq(friend.getID().getCharacterID().getID())
.field(name(e.characterIdFriend))
.eq(friend.getID().getFriendID());
}
});
}
@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

@@ -0,0 +1,149 @@
/*
* 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.orientdb;
import java.util.List;
import com.google.inject.Inject;
import com.l2jserver.model.Model;
import com.l2jserver.model.dao.CharacterFriendDAO;
import com.l2jserver.model.dao.CharacterShortcutDAO;
import com.l2jserver.model.game.CharacterShortcut;
import com.l2jserver.model.id.CharacterShortcutID;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.mapper.CharacterShortcutMapper;
import com.l2jserver.service.database.model.QCharacterShortcut;
import com.l2jserver.service.database.orientdb.AbstractOrientDBDAO;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.DeleteQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.InsertQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectSingleQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.UpdateQuery;
import com.orientechnologies.orient.core.query.nativ.OQueryContextNative;
/**
* {@link CharacterFriendDAO} implementation for JDBC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBCharacterShortcutDAO extends
AbstractOrientDBDAO<CharacterShortcut, CharacterShortcutID> implements
CharacterShortcutDAO {
private final CharacterShortcutMapper mapper;
/**
* @param database
* the database service
* @param mapper
* the {@link CharacterShortcut} mapper
*/
@Inject
public OrientDBCharacterShortcutDAO(DatabaseService database,
CharacterShortcutMapper mapper) {
super(database);
this.mapper = mapper;
}
@Override
public CharacterShortcut select(final CharacterShortcutID id) {
return database
.query(new SelectSingleQuery<CharacterShortcut, Integer, CharacterShortcutID, QCharacterShortcut>(
QCharacterShortcut.characterShortcut, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacterShortcut e) {
return record.field(name(e.shortcutId)).eq(id.getID());
}
});
}
@Override
public List<CharacterShortcut> selectByCharacter(final L2Character character) {
return database
.query(new SelectListQuery<CharacterShortcut, Integer, CharacterShortcutID, QCharacterShortcut>(
QCharacterShortcut.characterShortcut, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacterShortcut e) {
return record.field(name(e.characterId)).eq(
character.getID().getID());
}
});
}
@Override
public List<CharacterShortcutID> selectIDs() {
return database
.query(new SelectListQuery<CharacterShortcutID, Integer, CharacterShortcutID, QCharacterShortcut>(
QCharacterShortcut.characterShortcut,
mapper.getIDMapper(QCharacterShortcut.characterShortcut)) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QCharacterShortcut e) {
return record;
}
});
}
@Override
public int insertObjects(CharacterShortcut... shortcuts) {
return database
.query(new InsertQuery<CharacterShortcut, Integer, CharacterShortcutID, QCharacterShortcut>(
QCharacterShortcut.characterShortcut, mapper,
QCharacterShortcut.characterShortcut.shortcutId,
shortcuts));
}
@Override
public int updateObjects(CharacterShortcut... shortcuts) {
return database
.query(new UpdateQuery<CharacterShortcut, QCharacterShortcut>(
QCharacterShortcut.characterShortcut, mapper, shortcuts) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, CharacterShortcut o) {
return record.field(name(e.shortcutId)).eq(
o.getID().getID());
}
});
}
@Override
public int deleteObjects(CharacterShortcut... shortcuts) {
return database
.query(new DeleteQuery<CharacterShortcut, QCharacterShortcut>(
QCharacterShortcut.characterShortcut, shortcuts) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, CharacterShortcut o) {
return record.field(name(e.shortcutId)).eq(
o.getID().getID());
}
});
}
@Override
protected CharacterShortcut[] wrap(Model<?>... objects) {
final CharacterShortcut[] array = new CharacterShortcut[objects.length];
int i = 0;
for (final Model<?> object : objects) {
array[i++] = (CharacterShortcut) object;
}
return array;
}
}

View File

@@ -0,0 +1,120 @@
/*
* 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.orientdb;
import java.util.Collection;
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.server.ChatMessage;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.mapper.ChatMessageMapper;
import com.l2jserver.service.database.model.QLogChat;
import com.l2jserver.service.database.orientdb.AbstractOrientDBDAO;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.DeleteQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.InsertQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectSingleQuery;
import com.orientechnologies.orient.core.query.nativ.OQueryContextNative;
/**
* {@link CharacterDAO} implementation for JDBC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBChatMessageDAO extends
AbstractOrientDBDAO<ChatMessage, ChatMessageID> implements
ChatMessageDAO {
private final ChatMessageMapper mapper;
/**
* @param database
* the database service
* @param mapper
* the mapper
*/
@Inject
public OrientDBChatMessageDAO(DatabaseService database,
ChatMessageMapper mapper) {
super(database);
this.mapper = mapper;
}
@Override
public ChatMessage select(final ChatMessageID id) {
return database
.query(new SelectSingleQuery<ChatMessage, Integer, ChatMessageID, QLogChat>(
QLogChat.logChat, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QLogChat e) {
return record.field(name(e.messageId)).eq(id.getID());
}
});
}
@Override
public Collection<ChatMessageID> selectIDs() {
return database
.query(new SelectListQuery<ChatMessageID, Integer, ChatMessageID, QLogChat>(
QLogChat.logChat, mapper.getIDMapper(QLogChat.logChat)) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QLogChat e) {
return record;
}
});
}
@Override
public int insertObjects(ChatMessage... objects) {
return database
.query(new InsertQuery<ChatMessage, Integer, ChatMessageID, QLogChat>(
QLogChat.logChat, mapper, QLogChat.logChat.messageId,
objects));
}
@Override
public int updateObjects(ChatMessage... objects) {
return 0;
}
@Override
public int deleteObjects(ChatMessage... objects) {
return database.query(new DeleteQuery<ChatMessage, QLogChat>(
QLogChat.logChat, objects) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
ChatMessage o) {
return record.field(name(e.messageId)).eq(o.getID().getID());
}
});
}
@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

@@ -0,0 +1,123 @@
/*
* 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.orientdb;
import java.util.Collection;
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.object.ClanID;
import com.l2jserver.model.world.Clan;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.mapper.ClanMapper;
import com.l2jserver.service.database.model.QClan;
import com.l2jserver.service.database.orientdb.AbstractOrientDBDAO;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.DeleteQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.InsertQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectSingleQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.UpdateQuery;
import com.orientechnologies.orient.core.query.nativ.OQueryContextNative;
/**
* {@link CharacterDAO} implementation for JDBC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBClanDAO extends AbstractOrientDBDAO<Clan, ClanID> implements ClanDAO {
private final ClanMapper mapper;
/**
* @param database
* the database service
* @param mapper
* the mapper
*/
@Inject
public OrientDBClanDAO(DatabaseService database, final ClanMapper mapper) {
super(database);
this.mapper = mapper;
}
@Override
public Clan select(final ClanID id) {
return database
.query(new SelectSingleQuery<Clan, Integer, ClanID, QClan>(
QClan.clan, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QClan e) {
return record.field(name(e.clanId)).eq(id.getID());
}
});
}
@Override
public Collection<ClanID> selectIDs() {
return database
.query(new SelectListQuery<ClanID, Integer, ClanID, QClan>(
QClan.clan, mapper.getIDMapper(QClan.clan)) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QClan e) {
return record;
}
});
}
@Override
public int insertObjects(Clan... objects) {
return database.query(new InsertQuery<Clan, Integer, ClanID, QClan>(
QClan.clan, mapper, QClan.clan.clanId, objects));
}
@Override
public int updateObjects(Clan... objects) {
return database.query(new UpdateQuery<Clan, QClan>(QClan.clan, mapper,
objects) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
Clan o) {
return record.field(name(e.clanId)).eq(o.getID().getID());
}
});
}
@Override
public int deleteObjects(Clan... objects) {
return database
.query(new DeleteQuery<Clan, QClan>(QClan.clan, objects) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, Clan o) {
return record.field(name(e.clanId)).eq(o.getID().getID());
}
});
}
@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

@@ -0,0 +1,154 @@
/*
* 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.orientdb;
import java.util.Collection;
import java.util.List;
import com.google.inject.Inject;
import com.l2jserver.model.Model;
import com.l2jserver.model.dao.ItemDAO;
import com.l2jserver.model.id.object.ItemID;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.character.CharacterInventory.ItemLocation;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.mapper.ItemMapper;
import com.l2jserver.service.database.model.QItem;
import com.l2jserver.service.database.orientdb.AbstractOrientDBDAO;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.DeleteQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.InsertQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectSingleQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.UpdateQuery;
import com.orientechnologies.orient.core.query.nativ.OQueryContextNative;
/**
* {@link ItemDAO} implementation for JDBC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBItemDAO extends AbstractOrientDBDAO<Item, ItemID>
implements ItemDAO {
private final ItemMapper mapper;
/**
* @param database
* the database service
* @param mapper
* the mapper
*/
@Inject
public OrientDBItemDAO(DatabaseService database, ItemMapper mapper) {
super(database);
this.mapper = mapper;
}
@Override
public Item select(final ItemID id) {
return database
.query(new SelectSingleQuery<Item, Integer, ItemID, QItem>(
QItem.item, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QItem e) {
return record.field(name(e.itemId)).eq(id.getID());
}
});
}
@Override
public List<Item> selectByCharacter(final L2Character character) {
return database
.query(new SelectListQuery<Item, Integer, ItemID, QItem>(
QItem.item, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QItem e) {
return record.field(name(e.characterId)).eq(
character.getID().getID());
}
});
}
@Override
public List<Item> selectDroppedItems() {
return database
.query(new SelectListQuery<Item, Integer, ItemID, QItem>(
QItem.item, mapper) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QItem e) {
return record.field(name(e.itemId)).eq(
ItemLocation.GROUND);
}
});
}
@Override
public Collection<ItemID> selectIDs() {
return database
.query(new SelectListQuery<ItemID, Integer, ItemID, QItem>(
QItem.item, mapper.getIDMapper(QItem.item)) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, QItem e) {
return record;
}
});
}
@Override
public int insertObjects(Item... objects) {
return database.query(new InsertQuery<Item, Integer, ItemID, QItem>(
QItem.item, mapper, objects));
}
@Override
public int updateObjects(Item... objects) {
return database.query(new UpdateQuery<Item, QItem>(QItem.item, mapper,
objects) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
Item o) {
return record.field(name(e.itemId)).eq(o.getID().getID());
}
});
}
@Override
public int deleteObjects(Item... objects) {
return database
.query(new DeleteQuery<Item, QItem>(QItem.item, objects) {
@Override
protected OQueryContextNative query(
OQueryContextNative record, Item o) {
return record.field(name(e.itemId)).eq(o.getID().getID());
}
});
}
@Override
protected Item[] wrap(Model<?>... objects) {
final Item[] array = new Item[objects.length];
int i = 0;
for (final Model<?> object : objects) {
array[i++] = (Item) object;
}
return array;
}
}

View File

@@ -0,0 +1,148 @@
/*
* 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.orientdb;
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.dao.NPCDAO;
import com.l2jserver.model.id.object.NPCID;
import com.l2jserver.model.id.template.NPCTemplateID;
import com.l2jserver.model.world.NPC;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.mapper.NPCMapper;
import com.l2jserver.service.database.model.QNPC;
import com.l2jserver.service.database.orientdb.AbstractOrientDBDAO;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.DeleteQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.InsertQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectListQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.SelectSingleQuery;
import com.l2jserver.service.database.orientdb.AbstractOrientDatabaseService.UpdateQuery;
import com.orientechnologies.orient.core.query.nativ.OQueryContextNative;
/**
* {@link CharacterDAO} implementation for JDBC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class OrientDBNPCDAO extends AbstractOrientDBDAO<NPC, NPCID> implements
NPCDAO {
private final NPCMapper mapper;
/**
* @param database
* the database service
* @param mapper
* the mapper
*/
@Inject
public OrientDBNPCDAO(DatabaseService database, NPCMapper mapper) {
super(database);
this.mapper = mapper;
}
@Override
public NPC select(final NPCID id) {
return database.query(new SelectSingleQuery<NPC, Integer, NPCID, QNPC>(
QNPC.npc, mapper) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
QNPC e) {
return record.field(name(e.npcId)).eq(id.getID());
}
});
}
@Override
public Collection<NPC> loadAll() {
return database.query(new SelectListQuery<NPC, Integer, NPCID, QNPC>(
QNPC.npc, mapper) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
QNPC e) {
return null;
}
});
}
@Override
public List<NPC> selectByTemplate(final NPCTemplateID templateID) {
return database.query(new SelectListQuery<NPC, Integer, NPCID, QNPC>(
QNPC.npc, mapper) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
QNPC e) {
return record.field(name(e.npcTemplateId)).eq(
templateID.getID());
}
});
}
@Override
public Collection<NPCID> selectIDs() {
return database.query(new SelectListQuery<NPCID, Integer, NPCID, QNPC>(
QNPC.npc, mapper.getIDMapper(QNPC.npc)) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
QNPC e) {
return record;
}
});
}
@Override
public int insertObjects(NPC... objects) {
return database.query(new InsertQuery<NPC, Integer, NPCID, QNPC>(
QNPC.npc, mapper, objects));
}
@Override
public int updateObjects(NPC... objects) {
return database.query(new UpdateQuery<NPC, QNPC>(QNPC.npc, mapper,
objects) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
NPC o) {
return record.field(name(e.npcId)).eq(o.getID().getID());
}
});
}
@Override
public int deleteObjects(NPC... objects) {
return database.query(new DeleteQuery<NPC, QNPC>(QNPC.npc, objects) {
@Override
protected OQueryContextNative query(OQueryContextNative record,
NPC o) {
return record.field(name(e.npcId)).eq(o.getID().getID());
}
});
}
@Override
protected NPC[] wrap(Model<?>... objects) {
final NPC[] array = new NPC[objects.length];
int i = 0;
for (final Model<?> object : objects) {
array[i++] = (NPC) object;
}
return array;
}
}

View File

@@ -34,30 +34,6 @@ import com.l2jserver.service.database.model.QCharacterFriend;
*/
public class CharacterFriendMapper extends
AbstractMapper<CharacterFriend, FriendID, FriendID, QCharacterFriend> {
// private final CompoundPrimaryKeyMapper<FriendID, CharacterID,
// CharacterID, QCharacterFriend> idMapper = new
// CompoundPrimaryKeyMapper<FriendID, CharacterID, CharacterID,
// QCharacterFriend>() {
// @Override
// public AbstractCompoundID<CharacterID, CharacterID> raw(
// QCharacterFriend entity, DatabaseRow row) {
// return createID(entity, row);
// }
//
// @Override
// public FriendID createID(QCharacterFriend entity, DatabaseRow row) {
// return idProvider.createID(
// charIdProvider.resolveID(row.get(e.characterId)),
// charIdProvider.resolveID(row.get(e.characterIdFriend)));
// }
//
// @Override
// public FriendID generated(
// AbstractCompoundID<CharacterID, CharacterID> raw) {
// return null;
// }
// };
/**
* The {@link CharacterID} provider
*/

View File

@@ -75,6 +75,7 @@ public class NPCMapper extends AbstractMapper<NPC, Integer, NPCID, QNPC> {
@Override
public NPC select(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();

View File

@@ -3,7 +3,7 @@ package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.model.game.Skill;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.sql.RelationalPathBase;
import com.mysema.query.types.Path;

View File

@@ -5,13 +5,11 @@ 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.Clan;
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.sql.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.mysema.query.sql.ForeignKey;
import com.l2jserver.service.database.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.sql.RelationalPathBase;
import com.mysema.query.types.Path;
@@ -82,7 +80,7 @@ public class QCharacter extends RelationalPathBase<Integer> {
"apperance_face", CharacterFace.class);
public final PrimaryKey<Integer> primary = createPrimaryKey(characterId);
public final ForeignKey<Clan> clanIdKey = createForeignKey(clanId, "");
//public final ForeignKey<Clan> clanIdKey = createForeignKey(clanId, "");
public QCharacter(String variable) {
super(Integer.class, forVariable(variable), "null", "character");

View File

@@ -3,7 +3,7 @@ package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.model.id.FriendID;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;

View File

@@ -3,9 +3,9 @@ package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.model.game.CharacterShortcut.ShortcutType;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnAutoIncrement;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.l2jserver.service.database.ddl.annotation.ColumnAutoIncrement;
import com.l2jserver.service.database.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;

View File

@@ -2,7 +2,7 @@ package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;

View File

@@ -4,9 +4,9 @@ import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
import com.l2jserver.model.world.character.CharacterInventory.ItemLocation;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnDefault;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.l2jserver.service.database.ddl.annotation.ColumnDefault;
import com.l2jserver.service.database.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;

View File

@@ -4,9 +4,9 @@ import static com.mysema.query.types.PathMetadataFactory.forVariable;
import java.util.Date;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnAutoIncrement;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.l2jserver.service.database.ddl.annotation.ColumnAutoIncrement;
import com.l2jserver.service.database.ddl.annotation.ColumnNullable;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.l2jserver.service.game.chat.ChatMessageType;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;

View File

@@ -2,7 +2,7 @@ package com.l2jserver.service.database.model;
import static com.mysema.query.types.PathMetadataFactory.forVariable;
import com.l2jserver.service.database.sql.ddl.annotation.ColumnSize;
import com.l2jserver.service.database.ddl.annotation.ColumnSize;
import com.mysema.query.sql.PrimaryKey;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathMetadata;

View File

@@ -152,6 +152,7 @@ public class NPCServiceImpl extends AbstractService implements NPCService {
for (final NPC npc : npcs) {
spawnService.spawn(npc, null);
}
log.info("Loaded {} NPC instances", npcs.size());
} catch (SpawnPointNotFoundServiceException e) {
throw new ServiceStartException(e);
} catch (AlreadySpawnedServiceException e) {

View File

@@ -50,8 +50,7 @@ public class MySQL5CharacterDAOTest {
@Test
public void testCachedLoad() throws ServiceStartException {
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);
final CharacterDAO dao = injector.getInstance(CharacterDAO.class);

View File

@@ -16,16 +16,21 @@
*/
package com.l2jserver.service.database;
import java.io.IOException;
import java.nio.file.Path;
import java.sql.Connection;
import java.sql.SQLException;
import com.l2jserver.model.Model;
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.core.vfs.VFSService;
import com.l2jserver.service.database.dao.SelectMapper;
import com.l2jserver.service.database.sql.AbstractSQLDatabaseService;
import com.mysema.query.sql.RelationalPathBase;
/**
* This is an implementation of {@link DatabaseService} that provides an layer

View File

@@ -1,33 +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.tool.ddl;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class GenerateSQLFiles {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}

View File

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