Skip to content
Snippets Groups Projects
Commit 2a061fc2 authored by gwen-soleil's avatar gwen-soleil
Browse files

WIP: start implementing MySQL

parent 98d8f2fe
Branches
No related tags found
No related merge requests found
Showing
with 376 additions and 183 deletions
...@@ -72,6 +72,7 @@ public class MySqlArchivingConfigWriter { ...@@ -72,6 +72,7 @@ public class MySqlArchivingConfigWriter {
logger.info(" attributeConfig = {}", attributeConfig); logger.info(" attributeConfig = {}", attributeConfig);
if (!idBefore.isPresent() || idBefore.getAsInt() <= 0) { if (!idBefore.isPresent() || idBefore.getAsInt() <= 0) {
// register new attribute // register new attribute
// TODO create table for attribute
logger.info("starting {} for the first time on {}", attributeName, archiverDeviceName); logger.info("starting {} for the first time on {}", attributeName, archiverDeviceName);
newId = OptionalInt.of(jdbi.withExtension(MySqlAttributeConfigCommands.class, dao -> dao.insert(attributeName, newId = OptionalInt.of(jdbi.withExtension(MySqlAttributeConfigCommands.class, dao -> dao.insert(attributeName,
attributeConfig.getType(), attributeConfig.getType(),
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
package fr.soleil.tango.archiving.config.db.mysql.tables; package fr.soleil.tango.archiving.config.db.mysql.tables;
import fr.soleil.tango.archiving.config.AttributeConfig; import fr.soleil.tango.archiving.config.AttributeConfig;
import fr.soleil.tango.archiving.config.db.mysql.utils.MySqlUtilities;
public class MySqlAttributeConfigMapper { public class MySqlAttributeConfigMapper {
...@@ -54,7 +55,10 @@ public class MySqlAttributeConfigMapper { ...@@ -54,7 +55,10 @@ public class MySqlAttributeConfigMapper {
config.setFormat(table.getFormat()); config.setFormat(table.getFormat());
config.setType(table.getType()); config.setType(table.getType());
config.setTime(table.getTime()); config.setTime(table.getTime());
config.setTableName(MySqlUtilities.getTableName(table.getAttConfId()));
} }
return config; return config;
} }
} }
/* /*
* Copyright (c) 2024. * Copyright (c) 2025.
* *
* Synchrotron Soleil * Synchrotron Soleil
* L'Orme des merisiers * L'Orme des merisiers
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* gwenaelle.abeille@synchrotron-soleil.fr * gwenaelle.abeille@synchrotron-soleil.fr
* *
* This software is a computer program whose purpose is to provide TANGO archived data through a GraphQL API. * This software is a computer program whose purpose is to provide an Java API for managing insertion and fetching of Tango data into a database
* *
* This software is governed by the CeCILL license under French law and abiding by the rules of distribution of free software. * This software is governed by the CeCILL license under French law and abiding by the rules of distribution of free software.
* You can use, modify and/ or redistribute the software under the terms of the CeCILL license as circulated by CEA, CNRS and * You can use, modify and/ or redistribute the software under the terms of the CeCILL license as circulated by CEA, CNRS and
...@@ -30,22 +30,21 @@ ...@@ -30,22 +30,21 @@
* terms. * terms.
*/ */
package fr.soleil.tango.archiving.infra.injection; package fr.soleil.tango.archiving.config.db.mysql.utils;
import com.google.inject.AbstractModule; public class MySqlUtilities {
import fr.soleil.database.connection.DataBaseParameters;
import fr.soleil.tango.archiving.event.db.legacy.insert.LegacyAttributeInserter;
import fr.soleil.tango.archiving.event.insert.IAttributeInserter;
public class LegacyModuleInjector extends AbstractModule { public static String getTableName(final int index) {
private final DataBaseParameters dataBaseParameters; String tableName = "att_";
if (index < 10) {
public LegacyModuleInjector(final DataBaseParameters dataBaseParameters) { tableName = tableName + "0000" + index;
this.dataBaseParameters = dataBaseParameters; } else if (index < 100) {
tableName = tableName + "000" + index;
} else if (index < 1000) {
tableName = tableName + "00" + index;
} else { // if (index < 10000) {
tableName = tableName + "0" + index;
} }
return tableName;
@Override
protected void configure() {
bind(IAttributeInserter.class).toInstance(new LegacyAttributeInserter(dataBaseParameters));
} }
} }
/*
* Copyright (c) 2024.
*
* Synchrotron Soleil
* L'Orme des merisiers
* Saint Aubin
* BP48
* 91192 GIF-SUR-YVETTE CEDEX
*
* gwenaelle.abeille@synchrotron-soleil.fr
*
* This software is a computer program whose purpose is to provide TANGO archived data through a GraphQL API.
*
* This software is governed by the CeCILL license under French law and abiding by the rules of distribution of free software.
* You can use, modify and/ or redistribute the software under the terms of the CeCILL license as circulated by CEA, CNRS and
* INRIA at the following URL "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license, users
* are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive
* licensors have only limited liability.
*
* In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or developing or
* reproducing the software by the user in light of its specific status of free software, that may mean that it is complicated to
* manipulate, and that also therefore means that it is reserved for developers and experienced professionals having
* in-depth computer knowledge. Users are therefore encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or data to be ensured and, more generally, to use and
* operate it in the same conditions as regards security.
*
* The fact that you are presently reading this means that you have had knowledge of the CeCILL license and that you accept its
* terms.
*/
package fr.soleil.tango.archiving.event.db.legacy.insert;
import com.google.inject.Inject;
import fr.esrf.Tango.AttrDataFormat;
import fr.esrf.Tango.AttrWriteType;
import fr.esrf.Tango.DevFailed;
import fr.soleil.archiving.common.api.ConnectionFactory;
import fr.soleil.archiving.common.api.exception.ArchivingException;
import fr.soleil.archiving.hdbtdb.api.management.attributes.adtapt.AdtAptAttributesFactory;
import fr.soleil.archiving.hdbtdb.api.management.attributes.adtapt.IAdtAptAttributes;
import fr.soleil.archiving.hdbtdb.api.management.attributes.hdb.insert.HdbAttributeInsertFactory;
import fr.soleil.archiving.hdbtdb.api.management.attributes.hdb.insert.IHdbAttributeInsert;
import fr.soleil.archiving.hdbtdb.api.tools.ScalarEvent;
import fr.soleil.archiving.hdbtdb.api.tools.SpectrumEvent_RO;
import fr.soleil.archiving.hdbtdb.api.tools.SpectrumEvent_RW;
import fr.soleil.database.connection.AbstractDataBaseConnector;
import fr.soleil.database.connection.DataBaseParameters;
import fr.soleil.tango.archiving.event.insert.AttributeEvent;
import fr.soleil.tango.archiving.event.insert.IAttributeInserter;
import fr.soleil.tango.archiving.exception.AttributeInsertionException;
import org.tango.attribute.AttributeTangoType;
import org.tango.utils.ArrayUtils;
@Deprecated
public class LegacyAttributeInserter implements IAttributeInserter {
private final IHdbAttributeInsert inserter;
@Inject
public LegacyAttributeInserter(DataBaseParameters params) {
try {
AbstractDataBaseConnector connector = ConnectionFactory.connect(params);
IAdtAptAttributes attributes = AdtAptAttributesFactory.getInstance(connector);
inserter = HdbAttributeInsertFactory.getInstance(connector, attributes);
} catch (ArchivingException e) {
throw new AttributeInsertionException(e);
}
}
@Override
public void insertScalar(AttributeEvent value, boolean withError) {
ScalarEvent event = new ScalarEvent();
event.setAttributeCompleteName(value.getFullName());
event.setTimeStamp(value.getDataTime().getTime());
event.setDataFormat(AttrDataFormat._SCALAR);
try {
event.setDataType(AttributeTangoType.getTypeFromClass(value.getValueR().getClass()).getTangoIDLType());
} catch (DevFailed devFailed) {
throw new AttributeInsertionException(devFailed);
}
if (value.getValueW() != null) {
Object val = new Object[]{value.getValueR(), value.getValueW()};
event.setValue(val, null);
event.setWritable(AttrWriteType._READ_WRITE);
} else {
event.setValue(value.getValueR(), null);
event.setWritable(AttrWriteType._READ);
}
try {
inserter.insert_ScalarData(event);
} catch (ArchivingException e) {
throw new AttributeInsertionException(e);
}
}
@Override
public void insertArray(AttributeEvent value, boolean withError) {
if (value.getValueW() == null) {
SpectrumEvent_RO spectrumEventRo = new SpectrumEvent_RO();
spectrumEventRo.setAttributeCompleteName(value.getFullName());
spectrumEventRo.setTimeStamp(value.getDataTime().getTime());
spectrumEventRo.setDataFormat(AttrDataFormat._SPECTRUM);
spectrumEventRo.setValue(value.getValueR(), null);
try {
spectrumEventRo.setDataType(AttributeTangoType.getTypeFromClass(value.getValueR().getClass()).getTangoIDLType());
} catch (DevFailed devFailed) {
throw new AttributeInsertionException(devFailed);
}
try {
inserter.insert_SpectrumData_RO(spectrumEventRo);
} catch (ArchivingException e) {
throw new AttributeInsertionException(e);
}
} else {
SpectrumEvent_RW spectrumEventRw = new SpectrumEvent_RW();
spectrumEventRw.setAttributeCompleteName(value.getFullName());
spectrumEventRw.setTimeStamp(value.getDataTime().getTime());
spectrumEventRw.setDataFormat(AttrDataFormat._SPECTRUM);
spectrumEventRw.setValue(ArrayUtils.addAll(value.getValueR(), value.getValueW()), null);
try {
spectrumEventRw.setDataType(AttributeTangoType.getTypeFromClass(value.getValueR().getClass()).getTangoIDLType());
} catch (DevFailed devFailed) {
throw new AttributeInsertionException(devFailed);
}
try {
inserter.insert_SpectrumData_RW(spectrumEventRw);
} catch (ArchivingException e) {
throw new AttributeInsertionException(e);
}
}
}
@Override
public void batchInsertScalar(String tableName, boolean withError, AttributeEvent... values) {
}
}
...@@ -54,15 +54,13 @@ public class MySqlAttributeInserter implements IAttributeInserter { ...@@ -54,15 +54,13 @@ public class MySqlAttributeInserter implements IAttributeInserter {
@Override @Override
public void insertScalar(AttributeEvent value, boolean withError) { public void insertScalar(AttributeEvent value, boolean withError) {
AttributeConfig attributeConfigDB = config.getAttribute(value.getFullName()); AttributeConfig attributeConfigDB = config.getAttribute(value.getFullName());
System.out.println("attributeConfigDB " + attributeConfigDB);
int writeType = attributeConfigDB.getWriteType(); int writeType = attributeConfigDB.getWriteType();
MySqlAttributeEventScalarTable toInsert = buildAttributeEvent(writeType, value, attributeConfigDB); MySqlAttributeEventScalarTable toInsert = buildAttributeEvent(writeType, value, attributeConfigDB);
String tableName = getTableName(attributeConfigDB.getId()); logger.debug("inserting {} into {}", toInsert, attributeConfigDB.getTableName());
logger.debug("inserting {} into {}", toInsert, tableName);
if (writeType == AttrWriteType._READ_WRITE) { if (writeType == AttrWriteType._READ_WRITE) {
jdbi.useExtension(MySqlAttributeScalarCommands.class, dao -> dao.insertRW(tableName, toInsert)); jdbi.useExtension(MySqlAttributeScalarCommands.class, dao -> dao.insertRW(attributeConfigDB.getTableName(), toInsert));
} else { } else {
jdbi.useExtension(MySqlAttributeScalarCommands.class, dao -> dao.insert(tableName, toInsert)); jdbi.useExtension(MySqlAttributeScalarCommands.class, dao -> dao.insert(attributeConfigDB.getTableName(), toInsert));
} }
} }
...@@ -78,19 +76,6 @@ public class MySqlAttributeInserter implements IAttributeInserter { ...@@ -78,19 +76,6 @@ public class MySqlAttributeInserter implements IAttributeInserter {
return toInsert; return toInsert;
} }
public String getTableName(final int index) {
String tableName = "att_";
if (index < 10) {
tableName = tableName + "0000" + index;
} else if (index < 100) {
tableName = tableName + "000" + index;
} else if (index < 1000) {
tableName = tableName + "00" + index;
} else { // if (index < 10000) {
tableName = tableName + "0" + index;
}
return tableName;
}
@Override @Override
public void insertArray(AttributeEvent value, boolean withError) { public void insertArray(AttributeEvent value, boolean withError) {
......
/*
* Copyright (c) 2025.
*
* Synchrotron Soleil
* L'Orme des merisiers
* Saint Aubin
* BP48
* 91192 GIF-SUR-YVETTE CEDEX
*
* gwenaelle.abeille@synchrotron-soleil.fr
*
* This software is a computer program whose purpose is to provide an Java API for managing insertion and fetching of Tango data into a database
*
* This software is governed by the CeCILL license under French law and abiding by the rules of distribution of free software.
* You can use, modify and/ or redistribute the software under the terms of the CeCILL license as circulated by CEA, CNRS and
* INRIA at the following URL "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license, users
* are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive
* licensors have only limited liability.
*
* In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or developing or
* reproducing the software by the user in light of its specific status of free software, that may mean that it is complicated to
* manipulate, and that also therefore means that it is reserved for developers and experienced professionals having
* in-depth computer knowledge. Users are therefore encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or data to be ensured and, more generally, to use and
* operate it in the same conditions as regards security.
*
* The fact that you are presently reading this means that you have had knowledge of the CeCILL license and that you accept its
* terms.
*/
package fr.soleil.tango.archiving.event.db.mysql.select;
import com.google.inject.Inject;
import fr.soleil.tango.archiving.config.AttributeConfig;
import fr.soleil.tango.archiving.config.db.mysql.select.MySqlArchivingConfigFetcher;
import fr.soleil.tango.archiving.event.db.mysql.table.MySqlAttributeValueSeriesMapper;
import fr.soleil.tango.archiving.event.select.AttributeValue;
import fr.soleil.tango.archiving.event.select.AttributeValueSeries;
import fr.soleil.tango.archiving.event.select.IArchivingAttributeFetcher;
import fr.soleil.tango.archiving.exception.TangoTimeseriesException;
import org.jdbi.v3.core.Jdbi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Timestamp;
public class MySqArchivingAttributeFetcher implements IArchivingAttributeFetcher {
private final Logger logger = LoggerFactory.getLogger(MySqArchivingAttributeFetcher.class);
@Inject
private Jdbi jdbi;
@Inject
private MySqlArchivingConfigFetcher config;
@Override
public AttributeValueSeries getSince(final String attributeName, final Timestamp since, final boolean withError) {
AttributeConfig attributeConfigDB = config.getAttribute(attributeName);
if (attributeConfigDB == null) {
throw new TangoTimeseriesException(attributeName + " has never been stored");
}
AttributeValueSeries values = jdbi.withExtension(MySqlAttributeQueries.class, dao ->
MySqlAttributeValueSeriesMapper.getAttributeValueSeries(attributeConfigDB,
dao.selectSince(attributeConfigDB.getTableName(), since)));
logger.debug("got {} values since {}", values.getAttributeValues().size(), since);
return values;
}
@Override
public AttributeValue getLast(final String attributeName, final boolean withError) {
return null;
}
@Override
public AttributeValueSeries getBetween(final String attributeName, final Timestamp startTime, final Timestamp endTime, final boolean withError) {
AttributeConfig attributeConfigDB = config.getAttribute(attributeName);
if (attributeConfigDB == null) {
throw new TangoTimeseriesException(attributeName + " has never been stored");
}
AttributeValueSeries values = jdbi.withExtension(MySqlAttributeQueries.class, dao ->
MySqlAttributeValueSeriesMapper.getAttributeValueSeries(attributeConfigDB,
dao.selectBetween(attributeConfigDB.getTableName(), startTime, endTime))
);
logger.debug("got {} values between {}/{}", values.getAttributeValues().size(), startTime, endTime);
return values;
}
@Override
public AttributeValueSeries getWithSampling(final String attributeName, final String sampling, final String aggregateFunction, final Timestamp startTime, final Timestamp endTime) {
return null;
}
@Override
public AttributeValue getClosestValue(final String attributeName, final Timestamp timestamp, final boolean withError) {
return null;
}
@Override
public AttributeValue getAggregateValue(final String attributeName, final String aggregateFunction, final Timestamp from, final Timestamp to) {
return null;
}
}
/*
* Copyright (c) 2024.
*
* Synchrotron Soleil
* L'Orme des merisiers
* Saint Aubin
* BP48
* 91192 GIF-SUR-YVETTE CEDEX
*
* gwenaelle.abeille@synchrotron-soleil.fr
*
* This software is a computer program whose purpose is to provide TANGO archived data through a GraphQL API.
*
* This software is governed by the CeCILL license under French law and abiding by the rules of distribution of free software.
* You can use, modify and/ or redistribute the software under the terms of the CeCILL license as circulated by CEA, CNRS and
* INRIA at the following URL "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license, users
* are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive
* licensors have only limited liability.
*
* In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or developing or
* reproducing the software by the user in light of its specific status of free software, that may mean that it is complicated to
* manipulate, and that also therefore means that it is reserved for developers and experienced professionals having
* in-depth computer knowledge. Users are therefore encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or data to be ensured and, more generally, to use and
* operate it in the same conditions as regards security.
*
* The fact that you are presently reading this means that you have had knowledge of the CeCILL license and that you accept its
* terms.
*/
package fr.soleil.tango.archiving.event.db.mysql.select;
import fr.soleil.tango.archiving.event.db.mysql.table.MySqlAttributeEventScalarTable;
import org.jdbi.v3.sqlobject.config.RegisterFieldMapper;
import org.jdbi.v3.sqlobject.customizer.Bind;
import org.jdbi.v3.sqlobject.customizer.Define;
import org.jdbi.v3.sqlobject.statement.SqlQuery;
import java.sql.Timestamp;
import java.util.List;
public interface MySqlAttributeQueries {
@SqlQuery("SELECT * FROM <tableName> WHERE time < :dataTime ORDER BY time")
@RegisterFieldMapper(MySqlAttributeEventScalarTable.class)
List<MySqlAttributeEventScalarTable> selectSince(@Define("tableName") String tableName, @Bind("dataTime") Timestamp dataTime);
@SqlQuery("select * from <tableName> WHERE time between :startTime and :endTime")
@RegisterFieldMapper(MySqlAttributeEventScalarTable.class)
List<MySqlAttributeEventScalarTable> selectBetween(@Define("tableName") String tableName,
@Bind("startTime") Timestamp startTime, @Bind("endTime") Timestamp endTime);
@SqlQuery("select att_conf_id, data_time, value_r, value_w, quality, att_error_desc_id, details " +
"from <tableName> where att_conf_id = :attConfID ORDER BY data_time DESC LIMIT 1")
@RegisterFieldMapper(MySqlAttributeEventScalarTable.class)
MySqlAttributeEventScalarTable selectLast(@Define("tableName") String tableName, @Bind("attConfID") int attConfID);
// SELECT time_bucket('30 minutes', data_time) AS bucket, avg(value_r) FROM att_scalar_devdouble
// WHERE att_conf_id = 1 GROUP BY bucket ORDER BY bucket ASC
@SqlQuery("SELECT time_bucket(<sampling>, data_time) AS bucket, " +
"<aggregateFunction>(value_r) AS value_r, <aggregateFunction>(value_w) AS value_w FROM <tableName> " +
"WHERE att_conf_id = :attConfID AND data_time > :startTime AND data_time < :endTime " +
"GROUP BY bucket ORDER BY bucket ASC")
@RegisterFieldMapper(MySqlAttributeEventScalarTable.class)
List<MySqlAttributeEventScalarTable> selectWithSampling(@Define("tableName") String tableName, @Bind("attConfID") int attConfID,
@Define("sampling") String sampling, @Define("aggregateFunction") String aggregateFunction,
@Bind("startTime") Timestamp startTime, @Bind("endTime") Timestamp endTime);
@SqlQuery("SELECT att_conf_id ,data_time, value_r, value_w, quality, details, att_error_desc_id FROM\n" +
"(\n" +
"(SELECT * FROM <tableName> WHERE data_time >= :attTimestamp and att_conf_id = :attConfID ORDER BY data_time LIMIT 1)\n" +
"UNION ALL\n" +
"(SELECT * FROM <tableName> WHERE data_time < :attTimestamp and att_conf_id = :attConfID ORDER BY data_time DESC LIMIT 1)\n" +
") as closest\n" +
" ORDER BY abs(extract(epoch from (data_time - :attTimestamp ))) LIMIT 1")
@RegisterFieldMapper(MySqlAttributeEventScalarTable.class)
MySqlAttributeEventScalarTable selectClosestValue(@Define("tableName") String tableName, @Bind("attConfID") int attributeID, @Bind("attTimestamp") Timestamp attTimestamp);
//select avg(value_r), avg(value_w) FROM att_scalar_devshort
// where att_conf_id = 1064 and data_time > '2022-03-27 16:40:46' AND data_time < '2023-03-27 16:40:46'
@SqlQuery("select <aggregateFunction>(value_r) as value_r, <aggregateFunction>(value_w) as value_w FROM <tableName>" +
" where att_conf_id = :attConfID and data_time > :startTime AND data_time < :endTime")
@RegisterFieldMapper(MySqlAttributeEventScalarTable.class)
MySqlAttributeEventScalarTable selectAggregateValue(
@Define("tableName") String tableName, @Define("aggregateFunction") String aggregateFunction,
@Bind("attConfID") int attributeID, @Bind("startTime") Timestamp startTime, @Bind("endTime") Timestamp endTime);
}
/*
* Copyright (c) 2024-2025.
*
* Synchrotron Soleil
* L'Orme des merisiers
* Saint Aubin
* BP48
* 91192 GIF-SUR-YVETTE CEDEX
*
* gwenaelle.abeille@synchrotron-soleil.fr
*
* This software is a computer program whose purpose is to provide an Java API for managing insertion and fetching of Tango data into a database
*
* This software is governed by the CeCILL license under French law and abiding by the rules of distribution of free software.
* You can use, modify and/ or redistribute the software under the terms of the CeCILL license as circulated by CEA, CNRS and
* INRIA at the following URL "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license, users
* are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive
* licensors have only limited liability.
*
* In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or developing or
* reproducing the software by the user in light of its specific status of free software, that may mean that it is complicated to
* manipulate, and that also therefore means that it is reserved for developers and experienced professionals having
* in-depth computer knowledge. Users are therefore encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or data to be ensured and, more generally, to use and
* operate it in the same conditions as regards security.
*
* The fact that you are presently reading this means that you have had knowledge of the CeCILL license and that you accept its
* terms.
*/
package fr.soleil.tango.archiving.event.db.mysql.table;
import fr.esrf.Tango.AttrWriteType;
import fr.soleil.tango.archiving.config.AttributeConfig;
import fr.soleil.tango.archiving.event.select.AttributeValue;
import fr.soleil.tango.archiving.event.select.AttributeValueSeries;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
public class MySqlAttributeValueSeriesMapper {
private final static Logger LOGGER = LoggerFactory.getLogger(MySqlAttributeValueSeriesMapper.class);
public static AttributeValueSeries getAttributeValueSeries(AttributeConfig attributeConfigDB, List<MySqlAttributeEventScalarTable> table) {
AttributeValueSeries valueSeries = new AttributeValueSeries();
valueSeries.setAttributeConfig(attributeConfigDB);
final List<AttributeValue> attributeValues = new ArrayList<>();
table.forEach(val -> attributeValues.add(MySqlAttributeValueSeriesMapper.getAttributeValue(val, attributeConfigDB.getWriteType())));
valueSeries.setAttributeValues(attributeValues);
return valueSeries;
}
public static AttributeValue getAttributeValue(MySqlAttributeEventScalarTable table, int writeType) {
AttributeValue value = new AttributeValue();
if (table != null) {
switch (writeType) {
case AttrWriteType._READ_WRITE:
Object readValue = table.getReadValue();
Object writeValue = table.getWriteValue();
LOGGER.debug("Value returned by db type is {}", readValue != null ? readValue.getClass().getCanonicalName() : "null");
value.setValueR(readValue);
value.setValueW(writeValue);
break;
case AttrWriteType._READ:
value.setValueR(table.getValue());
break;
case AttrWriteType._WRITE:
value.setValueW(table.getValue());
break;
}
value.setDataTime(table.getTime());
}
return value;
}
}
...@@ -36,8 +36,10 @@ import com.google.inject.Inject; ...@@ -36,8 +36,10 @@ import com.google.inject.Inject;
import fr.soleil.tango.archiving.config.AttributeConfig; import fr.soleil.tango.archiving.config.AttributeConfig;
import fr.soleil.tango.archiving.config.db.timescale.select.ArchivingConfigFetcher; import fr.soleil.tango.archiving.config.db.timescale.select.ArchivingConfigFetcher;
import fr.soleil.tango.archiving.event.db.timescale.tables.AttributeErrorTable; import fr.soleil.tango.archiving.event.db.timescale.tables.AttributeErrorTable;
import fr.soleil.tango.archiving.event.db.timescale.tables.AttributeValueSeriesMapper;
import fr.soleil.tango.archiving.event.select.AttributeValue; import fr.soleil.tango.archiving.event.select.AttributeValue;
import fr.soleil.tango.archiving.event.select.AttributeValueSeries; import fr.soleil.tango.archiving.event.select.AttributeValueSeries;
import fr.soleil.tango.archiving.event.select.IArchivingAttributeFetcher;
import fr.soleil.tango.archiving.exception.TangoTimeseriesException; import fr.soleil.tango.archiving.exception.TangoTimeseriesException;
import org.jdbi.v3.core.Jdbi; import org.jdbi.v3.core.Jdbi;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -46,7 +48,7 @@ import org.slf4j.LoggerFactory; ...@@ -46,7 +48,7 @@ import org.slf4j.LoggerFactory;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.Optional; import java.util.Optional;
public class ArchivingAttributeFetcher { public class ArchivingAttributeFetcher implements IArchivingAttributeFetcher {
private final Logger logger = LoggerFactory.getLogger(ArchivingAttributeFetcher.class); private final Logger logger = LoggerFactory.getLogger(ArchivingAttributeFetcher.class);
@Inject @Inject
...@@ -54,6 +56,7 @@ public class ArchivingAttributeFetcher { ...@@ -54,6 +56,7 @@ public class ArchivingAttributeFetcher {
@Inject @Inject
private ArchivingConfigFetcher config; private ArchivingConfigFetcher config;
@Override
public AttributeValueSeries getSince(String attributeName, Timestamp since, boolean withError) { public AttributeValueSeries getSince(String attributeName, Timestamp since, boolean withError) {
AttributeConfig attributeConfigDB = config.getAttribute(attributeName); AttributeConfig attributeConfigDB = config.getAttribute(attributeName);
if (attributeConfigDB == null) { if (attributeConfigDB == null) {
...@@ -73,6 +76,7 @@ public class ArchivingAttributeFetcher { ...@@ -73,6 +76,7 @@ public class ArchivingAttributeFetcher {
return values; return values;
} }
@Override
public AttributeValue getLast(String attributeName, boolean withError) { public AttributeValue getLast(String attributeName, boolean withError) {
AttributeConfig attributeConfigDB = config.getAttribute(attributeName); AttributeConfig attributeConfigDB = config.getAttribute(attributeName);
if (attributeConfigDB == null) { if (attributeConfigDB == null) {
...@@ -98,6 +102,7 @@ public class ArchivingAttributeFetcher { ...@@ -98,6 +102,7 @@ public class ArchivingAttributeFetcher {
} }
@Override
public AttributeValueSeries getBetween(String attributeName, Timestamp startTime, Timestamp endTime, boolean withError) { public AttributeValueSeries getBetween(String attributeName, Timestamp startTime, Timestamp endTime, boolean withError) {
AttributeConfig attributeConfigDB = config.getAttribute(attributeName); AttributeConfig attributeConfigDB = config.getAttribute(attributeName);
if (attributeConfigDB == null) { if (attributeConfigDB == null) {
...@@ -119,6 +124,7 @@ public class ArchivingAttributeFetcher { ...@@ -119,6 +124,7 @@ public class ArchivingAttributeFetcher {
return values; return values;
} }
@Override
public AttributeValueSeries getWithSampling(String attributeName, String sampling, String aggregateFunction, Timestamp startTime, Timestamp endTime) { public AttributeValueSeries getWithSampling(String attributeName, String sampling, String aggregateFunction, Timestamp startTime, Timestamp endTime) {
AttributeConfig attributeConfigDB = config.getAttribute(attributeName); AttributeConfig attributeConfigDB = config.getAttribute(attributeName);
if (attributeConfigDB == null) { if (attributeConfigDB == null) {
...@@ -133,6 +139,7 @@ public class ArchivingAttributeFetcher { ...@@ -133,6 +139,7 @@ public class ArchivingAttributeFetcher {
return buckets; return buckets;
} }
@Override
public AttributeValue getClosestValue(String attributeName, Timestamp timestamp, boolean withError) { public AttributeValue getClosestValue(String attributeName, Timestamp timestamp, boolean withError) {
AttributeConfig attributeConfigDB = config.getAttribute(attributeName); AttributeConfig attributeConfigDB = config.getAttribute(attributeName);
if (attributeConfigDB == null) { if (attributeConfigDB == null) {
...@@ -148,6 +155,7 @@ public class ArchivingAttributeFetcher { ...@@ -148,6 +155,7 @@ public class ArchivingAttributeFetcher {
return table; return table;
} }
@Override
public AttributeValue getAggregateValue(String attributeName, String aggregateFunction, Timestamp from, Timestamp to) { public AttributeValue getAggregateValue(String attributeName, String aggregateFunction, Timestamp from, Timestamp to) {
AttributeConfig attributeConfigDB = config.getAttribute(attributeName); AttributeConfig attributeConfigDB = config.getAttribute(attributeName);
if (attributeConfigDB == null) { if (attributeConfigDB == null) {
......
/* /*
* Copyright (c) 2024. * Copyright (c) 2024-2025.
* *
* Synchrotron Soleil * Synchrotron Soleil
* L'Orme des merisiers * L'Orme des merisiers
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* gwenaelle.abeille@synchrotron-soleil.fr * gwenaelle.abeille@synchrotron-soleil.fr
* *
* This software is a computer program whose purpose is to provide TANGO archived data through a GraphQL API. * This software is a computer program whose purpose is to provide an Java API for managing insertion and fetching of Tango data into a database
* *
* This software is governed by the CeCILL license under French law and abiding by the rules of distribution of free software. * This software is governed by the CeCILL license under French law and abiding by the rules of distribution of free software.
* You can use, modify and/ or redistribute the software under the terms of the CeCILL license as circulated by CEA, CNRS and * You can use, modify and/ or redistribute the software under the terms of the CeCILL license as circulated by CEA, CNRS and
...@@ -30,10 +30,9 @@ ...@@ -30,10 +30,9 @@
* terms. * terms.
*/ */
package fr.soleil.tango.archiving.event.db.timescale.select; package fr.soleil.tango.archiving.event.db.timescale.tables;
import fr.soleil.tango.archiving.config.AttributeConfig; import fr.soleil.tango.archiving.config.AttributeConfig;
import fr.soleil.tango.archiving.event.db.timescale.tables.AttributeEventScalarTable;
import fr.soleil.tango.archiving.event.select.AttributeValue; import fr.soleil.tango.archiving.event.select.AttributeValue;
import fr.soleil.tango.archiving.event.select.AttributeValueSeries; import fr.soleil.tango.archiving.event.select.AttributeValueSeries;
import org.slf4j.Logger; import org.slf4j.Logger;
......
/*
* Copyright (c) 2025.
*
* Synchrotron Soleil
* L'Orme des merisiers
* Saint Aubin
* BP48
* 91192 GIF-SUR-YVETTE CEDEX
*
* gwenaelle.abeille@synchrotron-soleil.fr
*
* This software is a computer program whose purpose is to provide an Java API for managing insertion and fetching of Tango data into a database
*
* This software is governed by the CeCILL license under French law and abiding by the rules of distribution of free software.
* You can use, modify and/ or redistribute the software under the terms of the CeCILL license as circulated by CEA, CNRS and
* INRIA at the following URL "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license, users
* are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive
* licensors have only limited liability.
*
* In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or developing or
* reproducing the software by the user in light of its specific status of free software, that may mean that it is complicated to
* manipulate, and that also therefore means that it is reserved for developers and experienced professionals having
* in-depth computer knowledge. Users are therefore encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or data to be ensured and, more generally, to use and
* operate it in the same conditions as regards security.
*
* The fact that you are presently reading this means that you have had knowledge of the CeCILL license and that you accept its
* terms.
*/
package fr.soleil.tango.archiving.event.select;
import java.sql.Timestamp;
public interface IArchivingAttributeFetcher {
AttributeValueSeries getSince(String attributeName, Timestamp since, boolean withError);
AttributeValue getLast(String attributeName, boolean withError);
AttributeValueSeries getBetween(String attributeName, Timestamp startTime, Timestamp endTime, boolean withError);
AttributeValueSeries getWithSampling(String attributeName, String sampling, String aggregateFunction, Timestamp startTime, Timestamp endTime);
AttributeValue getClosestValue(String attributeName, Timestamp timestamp, boolean withError);
AttributeValue getAggregateValue(String attributeName, String aggregateFunction, Timestamp from, Timestamp to);
}
...@@ -35,7 +35,9 @@ package fr.soleil.tango.archiving.infra.injection; ...@@ -35,7 +35,9 @@ package fr.soleil.tango.archiving.infra.injection;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariDataSource;
import fr.soleil.tango.archiving.event.db.mysql.insert.MySqlAttributeInserter; import fr.soleil.tango.archiving.event.db.mysql.insert.MySqlAttributeInserter;
import fr.soleil.tango.archiving.event.db.mysql.select.MySqArchivingAttributeFetcher;
import fr.soleil.tango.archiving.event.insert.IAttributeInserter; import fr.soleil.tango.archiving.event.insert.IAttributeInserter;
import fr.soleil.tango.archiving.event.select.IArchivingAttributeFetcher;
import fr.soleil.tango.archiving.infra.db.DataSourceConnection; import fr.soleil.tango.archiving.infra.db.DataSourceConnection;
import fr.soleil.tango.archiving.infra.tango.ITangoAttributeCache; import fr.soleil.tango.archiving.infra.tango.ITangoAttributeCache;
import fr.soleil.tango.archiving.infra.tango.TangoAttributeCache; import fr.soleil.tango.archiving.infra.tango.TangoAttributeCache;
...@@ -58,8 +60,8 @@ public class MySqlDBModuleInjector extends AbstractModule { ...@@ -58,8 +60,8 @@ public class MySqlDBModuleInjector extends AbstractModule {
bind(ITangoAttributeCache.class).toInstance(new TangoAttributeCache()); bind(ITangoAttributeCache.class).toInstance(new TangoAttributeCache());
bind(IAttributeInserter.class).toInstance(new MySqlAttributeInserter()); bind(IAttributeInserter.class).toInstance(new MySqlAttributeInserter());
// TODO MariaDB implementations // TODO MariaDB implementations
// bind(ArchivingAttributeFetcher.class).toInstance(new ArchivingAttributeFetcher()); bind(IArchivingAttributeFetcher.class).toInstance(new MySqArchivingAttributeFetcher());
// bind(ArchivingConfigFetcher.class).toInstance(new ArchivingConfigFetcher()); // bind(IArchivingConfigFetcher.class).toInstance(new ArchivingConfigFetcher());
} }
......
...@@ -39,6 +39,7 @@ import fr.soleil.tango.archiving.config.select.IArchivingConfigFetcher; ...@@ -39,6 +39,7 @@ import fr.soleil.tango.archiving.config.select.IArchivingConfigFetcher;
import fr.soleil.tango.archiving.event.db.timescale.insert.AttributeInserter; import fr.soleil.tango.archiving.event.db.timescale.insert.AttributeInserter;
import fr.soleil.tango.archiving.event.db.timescale.select.ArchivingAttributeFetcher; import fr.soleil.tango.archiving.event.db.timescale.select.ArchivingAttributeFetcher;
import fr.soleil.tango.archiving.event.insert.IAttributeInserter; import fr.soleil.tango.archiving.event.insert.IAttributeInserter;
import fr.soleil.tango.archiving.event.select.IArchivingAttributeFetcher;
import fr.soleil.tango.archiving.infra.db.DataSourceConnection; import fr.soleil.tango.archiving.infra.db.DataSourceConnection;
import fr.soleil.tango.archiving.infra.tango.ITangoAttributeCache; import fr.soleil.tango.archiving.infra.tango.ITangoAttributeCache;
import fr.soleil.tango.archiving.infra.tango.TangoAttributeCache; import fr.soleil.tango.archiving.infra.tango.TangoAttributeCache;
...@@ -60,7 +61,7 @@ public class TimeScaleModuleInjector extends AbstractModule { ...@@ -60,7 +61,7 @@ public class TimeScaleModuleInjector extends AbstractModule {
bind(DataSourceConnection.class).toInstance(connection); bind(DataSourceConnection.class).toInstance(connection);
bind(IAttributeInserter.class).toInstance(new AttributeInserter()); bind(IAttributeInserter.class).toInstance(new AttributeInserter());
bind(ITangoAttributeCache.class).toInstance(new TangoAttributeCache()); bind(ITangoAttributeCache.class).toInstance(new TangoAttributeCache());
bind(ArchivingAttributeFetcher.class).toInstance(new ArchivingAttributeFetcher()); bind(IArchivingAttributeFetcher.class).toInstance(new ArchivingAttributeFetcher());
bind(IArchivingConfigFetcher.class).toInstance(new ArchivingConfigFetcher()); bind(IArchivingConfigFetcher.class).toInstance(new ArchivingConfigFetcher());
} }
......
...@@ -35,10 +35,10 @@ package fr.soleil.tango.archiving.services; ...@@ -35,10 +35,10 @@ package fr.soleil.tango.archiving.services;
import com.google.inject.Inject; import com.google.inject.Inject;
import fr.soleil.tango.archiving.config.AttributeParameters; import fr.soleil.tango.archiving.config.AttributeParameters;
import fr.soleil.tango.archiving.config.select.IArchivingConfigFetcher; import fr.soleil.tango.archiving.config.select.IArchivingConfigFetcher;
import fr.soleil.tango.archiving.event.db.timescale.select.ArchivingAttributeFetcher;
import fr.soleil.tango.archiving.event.insert.AttributeEvent; import fr.soleil.tango.archiving.event.insert.AttributeEvent;
import fr.soleil.tango.archiving.event.select.AttributeValue; import fr.soleil.tango.archiving.event.select.AttributeValue;
import fr.soleil.tango.archiving.event.select.AttributeValueSeries; import fr.soleil.tango.archiving.event.select.AttributeValueSeries;
import fr.soleil.tango.archiving.event.select.IArchivingAttributeFetcher;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.Optional; import java.util.Optional;
...@@ -47,7 +47,7 @@ import java.util.OptionalInt; ...@@ -47,7 +47,7 @@ import java.util.OptionalInt;
public class TangoArchivingFetcherService { public class TangoArchivingFetcherService {
@Inject @Inject
private ArchivingAttributeFetcher archivingAttributeFetcher; private IArchivingAttributeFetcher archivingAttributeFetcher;
@Inject @Inject
private IArchivingConfigFetcher archivingConfigFetcher; private IArchivingConfigFetcher archivingConfigFetcher;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment