com.arcadedb.query.sql.parser.StatementCache Maven / Gradle / Ivy
/*
* Copyright © 2021-present Arcade Data Ltd ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-FileCopyrightText: 2021-present Arcade Data Ltd ([email protected])
* SPDX-License-Identifier: Apache-2.0
*/
package com.arcadedb.query.sql.parser;
import com.arcadedb.database.Database;
import com.arcadedb.database.DatabaseFactory;
import com.arcadedb.exception.CommandSQLParsingException;
import com.arcadedb.log.LogManager;
import java.io.*;
import java.nio.charset.*;
import java.util.*;
import java.util.logging.*;
/**
* This class is an LRU cache for already parsed SQL statement executors. It stores itself in the storage as a resource. It also
* acts an an entry point for the SQL parser.
*
* @author Luigi Dell'Aquila (luigi.dellaquila-(at)-gmail.com)
*/
public class StatementCache {
private final Database db;
private final Map map;
private final int mapSize;
/**
* @param size the size of the cache
*/
public StatementCache(final Database db, final int size) {
this.db = db;
this.mapSize = size;
this.map = new LinkedHashMap<>(size) {
protected boolean removeEldestEntry(final Map.Entry eldest) {
return super.size() > mapSize;
}
};
}
/**
* @param statement an SQL statement
*
* @return the corresponding executor, taking it from the internal cache, if it exists
*/
public Statement get(final String statement) {
Statement result;
synchronized (map) {
//LRU
result = map.remove(statement);
if (result != null) {
map.put(statement, result);
}
}
if (result == null) {
result = parse(statement);
synchronized (map) {
map.put(statement, result);
}
}
return result;
}
/**
* parses an SQL statement and returns the corresponding executor
*
* @param statement the SQL statement
*
* @return the corresponding executor
*
* @throws CommandSQLParsingException if the input parameter is not a valid SQL statement
*/
protected Statement parse(final String statement) throws CommandSQLParsingException {
try {
final InputStream is;
if (db == null) {
is = new ByteArrayInputStream(statement.getBytes(DatabaseFactory.getDefaultCharset()));
} else {
is = new ByteArrayInputStream(statement.getBytes(StandardCharsets.UTF_8));
}
SqlParser osql;
if (db == null) {
osql = new SqlParser(db, is);
} else {
try {
// osql = new SqlParser(is, db.getStorage().getConfiguration().getCharset());
osql = new SqlParser(db, is, "UTF-8");
} catch (final UnsupportedEncodingException e2) {
LogManager.instance().log(this, Level.WARNING, "Unsupported charset for database " + db);
osql = new SqlParser(db, is);
}
}
final Statement result = osql.Parse();
result.originalStatementAsString = statement;
return result;
} catch (final ParseException e) {
throwParsingException(e, statement);
} catch (final TokenMgrError e2) {
throwParsingException(e2, statement);
} catch (final Throwable e3) {
throwParsingException(e3, statement);
}
return null;
}
protected static void throwParsingException(final Throwable e, final String statement) {
throw new CommandSQLParsingException(statement, e);
}
protected static void throwParsingException(final TokenMgrError e, final String statement) {
throw new CommandSQLParsingException(statement, e);
}
public boolean contains(final String statement) {
synchronized (map) {
return map.containsKey(statement);
}
}
public void clear() {
synchronized (map) {
map.clear();
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy