
org.eclipse.basyx.tools.sqlproxy.SQLMap Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (C) 2021 the Eclipse BaSyx Authors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* SPDX-License-Identifier: MIT
******************************************************************************/
package org.eclipse.basyx.tools.sqlproxy;
import java.sql.ResultSet;
import java.util.AbstractMap;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.basyx.tools.sql.driver.ISQLDriver;
import org.eclipse.basyx.tools.sql.query.DynamicSQLQuery;
import org.eclipse.basyx.tools.sql.query.DynamicSQLUpdate;
/**
* This class implements a map that mirrors its contents into a SQL database
*
* - The map represents the root map that is linked into the SQL database as one
* table - Subsequent maps map to subsequent SQL tables
*
* A SQL table has the following structure: - name:text | type:integer |
* value:text
*
* @author kuhn
*
*/
public class SQLMap extends SQLProxy implements Map {
/**
* Constructor
*
* @param rootElement
* SQLRootElement for this element
* @param tableId
* Table ID of this element in SQL database
*/
public SQLMap(SQLRootElement rootElement, int tableId) {
// Invoke base constructor
super(rootElement.getDriver(), rootElement.getSqlTableID() + "__" + tableId, rootElement);
}
/**
* Constructor
*
* @param rootElement
* SQLRootElement for this element
* @param tableIdWithprefix
* Table ID of this element in SQL database with prefix
*/
public SQLMap(SQLRootElement rootElement, String tableIdWithprefix) {
// Invoke base constructor
super(rootElement.getDriver(), tableIdWithprefix, rootElement);
}
/**
* Constructor for creating a new SQLMap from another Map
*/
public SQLMap(SQLRootElement rootElement, Map other) {
this(rootElement, createMapTable(rootElement));
for (Entry entry : other.entrySet()) {
put(entry.getKey(), entry.getValue());
}
}
/**
* Create a new table for a map and return its generated id (relative to the
* root element)
*
* @return The table id in the root element scope
*/
private static int createMapTable(SQLRootElement rootElement) {
int tableId = rootElement.getNextIdentifier();
rootElement.createMap(tableId);
return tableId;
}
/**
* Get number of map elements
*/
@Override
public int size() {
// Build query string
String queryString = "SELECT * FROM elements." + getSqlTableID();
// - Build dynamic query
// - basically, the last parameter is not used here, as getRaw does not post
// process query results
DynamicSQLQuery dynQuery = new DynamicSQLQuery(getDriver(), queryString, "mapArray(name:String,value:String,type:String)");
// Execute query and get result set
ResultSet result = dynQuery.getRaw();
// Calculate size
return getSize(result);
}
/**
* Check if map is empty
*/
@Override
public boolean isEmpty() {
// Map is empty iff its size equals 0
return (size() == 0);
}
/**
* Check if map contains the given key (name)
*/
@Override
public boolean containsKey(Object key) {
// Use new driver for operation
return containsKey(getDriver(), key);
}
/**
* Check if map contains the given key (name)
*/
protected boolean containsKey(ISQLDriver drv, Object key) {
// Build query string
String queryString = "SELECT * FROM elements." + getSqlTableID() + " WHERE name='$name'";
// - Build dynamic query
// - basically, the last parameter is not used here, as getRaw does not post
// process query results
DynamicSQLQuery dynQuery = new DynamicSQLQuery(drv, queryString, "mapArray(name:String,value:String,type:String)");
// Build query parameter
Map parameter = new HashMap<>();
// - Put name in map
parameter.put("name", key);
// Execute query, get result set
ResultSet result = dynQuery.getRaw(parameter);
// Data base table contains key iff result set size > 1
return getSize(result) > 0;
}
/**
* Check if map contains the given value
*/
@Override
public boolean containsValue(Object value) {
// Use new driver for operation
return containsValue(getDriver(), value);
}
/**
* Check if map contains the given value
*/
protected boolean containsValue(ISQLDriver drv, Object value) {
// Build query string
String queryString = "SELECT * FROM elements." + getSqlTableID() + " WHERE value='$value'";
// - Build dynamic query
// - basically, the last parameter is not used here, as getRaw does not post
// process query results
DynamicSQLQuery dynQuery = new DynamicSQLQuery(drv, queryString, "mapArray(name:String,value:String,type:String)");
// Build query parameter
Map parameter = new HashMap<>();
// - Put name in map
parameter.put("value", SQLTableRow.getValueAsString(value));
// Execute query, get result set
ResultSet result = dynQuery.getRaw(parameter);
// Data base table contains key iff result set size > 1
return getSize(result) > 0;
}
/**
* Get value of map element that is identified by given key
*/
@Override
public Object get(Object key) {
// Get value from SQL database table
return getValueFromMap(getSqlTableID(), key.toString());
}
/**
* Put a key into a map
*/
@Override
public Object put(String key, Object value) {
putValue(getDriver(), key, value);
// Return inserted object
return value;
}
/**
* Puts arbitrary values in the map (even if they already exist). Does not
* commit the changes using the SQLDriver.
*/
protected void putValue(ISQLDriver sqlDrv, String key, Object value) {
value = convertToSimpleValue(value);
putSimpleValue(sqlDrv, key, value);
}
/**
* Puts simple values to the map (those, that can be directly converted to a
* table row). Does not commit the changes using the SQLDriver.
*/
private void putSimpleValue(ISQLDriver sqlDrv, String key, Object value) {
if (containsKey(sqlDrv, key)) {
updateInMapSimple(sqlDrv, getSqlTableID(), new SQLTableRow(key, value));
} else {
addToMapSimple(sqlDrv, getSqlTableID(), new SQLTableRow(key, value));
}
}
/**
* Converts arbitrary values to simple ones that can be directly added to the
* map's table as a single row. Currently, maps are supported. For arbitrary
* maps, a new table will be created that can then be referenced in this map.
*/
@SuppressWarnings("unchecked")
private Object convertToSimpleValue(Object value) {
// If the value is a map that can not be directly referenced by this root
// element
if (value instanceof Map && (!(value instanceof SQLMap) || !(((SQLMap) value).sqlRootElement.getSqlTableID().equals(sqlRootElement.getSqlTableID())))) {
// Create a new referable SQLMap out of the value in the scope of this root
// element
return new SQLMap(sqlRootElement, (Map) value);
}
return value;
}
/**
* Remove element with key from map
*/
@Override
public Object remove(Object key) {
// Return value
Object result = null;
// Get element from map for return value
result = getValueFromMap(getDriver(), getSqlTableID(), key.toString());
// Delete element from map
String updateString = "DELETE FROM elements." + getSqlTableID() + " WHERE name='$name'";
DynamicSQLUpdate dynUpdate = new DynamicSQLUpdate(getDriver(), updateString);
// Parameter map
Map parameter = new HashMap<>();
// - Put name in map
parameter.put("name", key);
// - Execute delete
dynUpdate.accept(parameter);
// Return element
return result;
}
/**
* Put all elements into map
*/
@Override
@SuppressWarnings("unchecked")
public void putAll(Map extends String, ? extends Object> map) {
// Remove old elements
removeAllKeys(getDriver(), (Set) map.keySet());
// Create map elements
Collection mapElements = new LinkedList<>();
// - Fill collection
for (String key : map.keySet()) {
mapElements.add(new SQLTableRow(key, map.get(key)));
}
// Add elements to map
addToMapMultiple(getDriver(), getSqlTableID(), mapElements);
}
/**
* Delete all map elements
*/
@Override
public void clear() {
// Build SQL update string
String updateString = "DELETE FROM elements." + getSqlTableID();
DynamicSQLUpdate dynUpdate = new DynamicSQLUpdate(getDriver(), updateString);
// Empty parameter set
Map parameter = new HashMap<>();
// Run SQL query
dynUpdate.accept(parameter);
}
/**
* Get the set of keys from SQL database
*/
@Override
@SuppressWarnings("unchecked")
public Set keySet() {
// Get key set - keys are stored in "name" column in table
return (Set) getSingleMapColumnRaw(getSqlTableID(), "name");
}
/**
* Get map values that are contained in the SQL database
*/
@Override
@SuppressWarnings("unchecked")
public Collection
© 2015 - 2025 Weber Informatics LLC | Privacy Policy