#region License Information
/* HeuristicLab
* Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab 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.
*
* HeuristicLab 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 HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using HeuristicLab.CEDMA.DB.Interfaces;
using System.ServiceModel;
using System.Data;
using System.Data.SQLite;
using System.Data.Common;
using System.Threading;
namespace HeuristicLab.CEDMA.DB {
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
public class Database : IDatabase {
private string connectionString;
private ReaderWriterLockSlim rwLock;
public Database(string connectionString) {
this.connectionString = connectionString;
rwLock = new ReaderWriterLockSlim();
}
#region create empty database
public void CreateNew() {
rwLock.EnterWriteLock();
try {
using(DbConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
using(DbTransaction t = cnn.BeginTransaction()) {
using(DbCommand cmd = cnn.CreateCommand()) {
cmd.CommandText = "CREATE TABLE Project (ID integer primary key autoincrement, Name text, Description text, CreationTime DateTime)";
cmd.Transaction = t;
cmd.ExecuteNonQuery();
}
using(DbCommand cmd = cnn.CreateCommand()) {
cmd.CommandText = "CREATE TABLE Agent (ID integer primary key autoincrement, ProjectId integer, ParentAgentId integer, Name text, Status text default " + ProcessStatus.Unknown + ", CreationTime DateTime, RawData Blob)";
cmd.Transaction = t;
cmd.ExecuteNonQuery();
}
using(DbCommand cmd = cnn.CreateCommand()) {
cmd.CommandText = "CREATE TABLE Result (ID integer primary key autoincrement, AgentId integer, ParentResultId integer, Summary text, Description text, CreationTime DateTime, RawData Blob)";
cmd.Transaction = t;
cmd.ExecuteNonQuery();
}
using(DbCommand cmd = cnn.CreateCommand()) {
cmd.CommandText = "CREATE TABLE Operator (ID integer primary key autoincrement, Name text, RawData Blob)";
cmd.Transaction = t;
cmd.ExecuteNonQuery();
}
t.Commit();
}
}
} finally {
rwLock.ExitWriteLock();
}
}
#endregion
#region insert agent/result/sub-result
public long InsertAgent(long? parentAgentId, string name, byte[] rawData) {
rwLock.EnterWriteLock();
try {
using(DbConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
long id;
using(DbTransaction t = cnn.BeginTransaction()) {
using(DbCommand c = cnn.CreateCommand()) {
c.Transaction = t;
c.CommandText = "Insert into Agent (Name, ParentAgentId, CreationTime, RawData) values (@Name, @ParentAgentId, @CreationTime, @RawData); select last_insert_rowid()";
DbParameter nameParam = c.CreateParameter();
nameParam.ParameterName = "@Name";
nameParam.Value = name;
c.Parameters.Add(nameParam);
DbParameter parentParam = c.CreateParameter();
parentParam.ParameterName = "@ParentAgentId";
parentParam.Value = parentAgentId;
c.Parameters.Add(parentParam);
DbParameter creationTimeParam = c.CreateParameter();
creationTimeParam.ParameterName = "@CreationTime";
creationTimeParam.Value = DateTime.Now;
c.Parameters.Add(creationTimeParam);
DbParameter dataParam = c.CreateParameter();
dataParam.ParameterName = "@RawData";
dataParam.Value = rawData;
c.Parameters.Add(dataParam);
id = (long)c.ExecuteScalar();
}
t.Commit();
return id;
}
}
} finally {
rwLock.ExitWriteLock();
}
}
public long InsertResult(long agentId, string summary, string description, byte[] rawData) {
rwLock.EnterWriteLock();
try {
using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
long id;
using(DbTransaction t = cnn.BeginTransaction()) {
using(DbCommand c = cnn.CreateCommand()) {
c.Transaction = t;
c.CommandText = "Insert into Result (AgentId, CreationTime, Summary, Description, RawData) values (@AgentId, @CreationTime, @Summary, @Description, @RawData); select last_insert_rowid()";
DbParameter agentIdParam = c.CreateParameter();
agentIdParam.ParameterName = "@AgentId";
agentIdParam.Value = agentId;
c.Parameters.Add(agentIdParam);
DbParameter creationParam = c.CreateParameter();
creationParam.ParameterName = "@CreationTime";
DateTime now = DateTime.Now;
creationParam.Value = now;
c.Parameters.Add(creationParam);
DbParameter summaryParam = c.CreateParameter();
summaryParam.ParameterName = "@Summary";
summaryParam.Value = summary;
c.Parameters.Add(summaryParam);
DbParameter descParam = c.CreateParameter();
descParam.ParameterName = "@Description";
descParam.Value = description;
c.Parameters.Add(descParam);
DbParameter rawDataParam = c.CreateParameter();
rawDataParam.ParameterName = "@RawData";
rawDataParam.Value = rawData;
c.Parameters.Add(rawDataParam);
id = (long)c.ExecuteScalar();
}
t.Commit();
return id;
}
}
} finally {
rwLock.ExitWriteLock();
}
}
public long InsertSubResult(long resultId, string summary, string description, byte[] rawData) {
rwLock.EnterWriteLock();
try {
using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
long id;
using(DbTransaction t = cnn.BeginTransaction()) {
using(DbCommand c = cnn.CreateCommand()) {
c.Transaction = t;
c.CommandText = "Insert into Result (ParentResultId, CreationTime, Summary, Description, RawData) values (@ParentResultId, @CreationTime, @Summary, @Description, @RawData); select last_insert_rowid()";
DbParameter resultIdParam = c.CreateParameter();
resultIdParam.ParameterName = "@ParentResultId";
resultIdParam.Value = resultId;
c.Parameters.Add(resultIdParam);
DbParameter creationParam = c.CreateParameter();
creationParam.ParameterName = "@CreationTime";
DateTime now = DateTime.Now;
creationParam.Value = now;
c.Parameters.Add(creationParam);
DbParameter summaryParam = c.CreateParameter();
summaryParam.ParameterName = "@Summary";
summaryParam.Value = summary;
c.Parameters.Add(summaryParam);
DbParameter descParam = c.CreateParameter();
descParam.ParameterName = "@Description";
descParam.Value = description;
c.Parameters.Add(descParam);
DbParameter rawDataParam = c.CreateParameter();
rawDataParam.ParameterName = "@RawData";
rawDataParam.Value = rawData;
c.Parameters.Add(rawDataParam);
id = (long)c.ExecuteScalar();
}
t.Commit();
return id;
}
}
} finally {
rwLock.ExitWriteLock();
}
}
public long InsertOperator(string name, byte[] rawData) {
rwLock.EnterWriteLock();
try {
using(DbConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
long id;
using(DbTransaction t = cnn.BeginTransaction()) {
using(DbCommand c = cnn.CreateCommand()) {
c.Transaction = t;
c.CommandText = "Insert into Operator (Name, RawData) values (@Name, @RawData); select last_insert_rowid()";
DbParameter nameParam = c.CreateParameter();
nameParam.ParameterName = "@Name";
nameParam.Value = name;
c.Parameters.Add(nameParam);
DbParameter dataParam = c.CreateParameter();
dataParam.ParameterName = "@RawData";
dataParam.Value = rawData;
c.Parameters.Add(dataParam);
id = (long)c.ExecuteScalar();
}
t.Commit();
return id;
}
}
} finally {
rwLock.ExitWriteLock();
}
}
#endregion
#region update agent, run, operator
public void UpdateAgent(long id, string name) {
rwLock.EnterWriteLock();
try {
using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
using(SQLiteTransaction t = cnn.BeginTransaction()) {
using(SQLiteCommand c = cnn.CreateCommand()) {
c.Transaction = t;
c.CommandText = "Update Agent set Name=@Name where id=@Id";
DbParameter nameParam = c.CreateParameter();
DbParameter idParam = c.CreateParameter();
nameParam.ParameterName = "@Name";
nameParam.Value = name;
idParam.ParameterName = "@Id";
idParam.Value = id;
c.Parameters.Add(nameParam);
c.Parameters.Add(idParam);
c.ExecuteNonQuery();
}
t.Commit();
}
}
} finally {
rwLock.ExitWriteLock();
}
}
public void UpdateAgent(long id, ProcessStatus status) {
rwLock.EnterWriteLock();
try {
using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
using(SQLiteTransaction t = cnn.BeginTransaction()) {
using(SQLiteCommand c = cnn.CreateCommand()) {
c.Transaction = t;
c.CommandText = "Update Agent set Status=@Status where id=@Id";
DbParameter statusParam = c.CreateParameter();
DbParameter idParam = c.CreateParameter();
statusParam.ParameterName = "@Status";
statusParam.Value = status.ToString();
idParam.ParameterName = "@Id";
idParam.Value = id;
c.Parameters.Add(statusParam);
c.Parameters.Add(idParam);
c.ExecuteNonQuery();
}
t.Commit();
}
}
} finally {
rwLock.ExitWriteLock();
}
}
public void UpdateAgent(long id, byte[] rawData) {
rwLock.EnterWriteLock();
try {
using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
using(SQLiteTransaction t = cnn.BeginTransaction()) {
using(SQLiteCommand c = cnn.CreateCommand()) {
c.Transaction = t;
c.CommandText = "Update Agent set RawData=@RawData where id=@Id";
DbParameter rawDataParam = c.CreateParameter();
DbParameter idParam = c.CreateParameter();
rawDataParam.ParameterName = "@RawData";
rawDataParam.Value = rawData;
idParam.ParameterName = "@Id";
idParam.Value = id;
c.Parameters.Add(rawDataParam);
c.Parameters.Add(idParam);
c.ExecuteNonQuery();
}
t.Commit();
}
}
} finally {
rwLock.ExitWriteLock();
}
}
public void UpdateOperator(long id, string name, byte[] rawData) {
rwLock.EnterWriteLock();
try {
using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
using(SQLiteTransaction t = cnn.BeginTransaction()) {
using(SQLiteCommand c = cnn.CreateCommand()) {
c.Transaction = t;
c.CommandText = "Update Operator set Name=@Name, RawData=@RawData where id=@Id";
DbParameter rawDataParam = c.CreateParameter();
DbParameter nameParam = c.CreateParameter();
DbParameter idParam = c.CreateParameter();
rawDataParam.ParameterName = "@RawData";
rawDataParam.Value = rawData;
idParam.ParameterName = "@Id";
idParam.Value = id;
nameParam.ParameterName = "@Name";
nameParam.Value = name;
c.Parameters.Add(rawDataParam);
c.Parameters.Add(nameParam);
c.Parameters.Add(idParam);
c.ExecuteNonQuery();
}
t.Commit();
}
}
} finally {
rwLock.ExitWriteLock();
}
}
#endregion
#region get agent/result/sub-result/operator
public ICollection GetAgents(ProcessStatus status) {
rwLock.EnterReadLock();
List agents = new List();
try {
using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
SQLiteCommand c = cnn.CreateCommand();
c.CommandText = "Select id, name from Agent where Status=@Status";
DbParameter statusParameter = c.CreateParameter();
statusParameter.ParameterName = "@Status";
statusParameter.Value = status.ToString();
c.Parameters.Add(statusParameter);
SQLiteDataReader r = c.ExecuteReader();
while(r.Read()) {
AgentEntry agent = new AgentEntry();
agent.ParentAgentId = null;
agent.Status = status;
agent.Id = r.GetInt32(0);
agent.Name = r.IsDBNull(1) ? "" : r.GetString(1);
agents.Add(agent);
}
}
} finally {
rwLock.ExitReadLock();
}
return agents;
}
public ICollection GetAgents() {
rwLock.EnterReadLock();
List agents = new List();
try {
using(DbConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
using(DbCommand c = cnn.CreateCommand()) {
c.CommandText = "Select id, name, status from Agent where ParentAgentId isnull";
using(DbDataReader r = c.ExecuteReader()) {
while(r.Read()) {
AgentEntry agent = new AgentEntry();
agent.ParentAgentId = null;
agent.Id = r.GetInt32(0);
agent.Name = r.IsDBNull(1) ? "-" : r.GetString(1);
agent.Status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), r.GetString(2));
agents.Add(agent);
}
}
}
}
} finally {
rwLock.ExitReadLock();
}
return agents;
}
public ICollection GetSubAgents(long parentAgentId) {
rwLock.EnterReadLock();
List agents = new List();
try {
using(DbConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
using(DbCommand c = cnn.CreateCommand()) {
c.CommandText = "Select id, name, status from Agent where ParentAgentId=@ParentAgentId";
DbParameter parentParameter = c.CreateParameter();
parentParameter.ParameterName = "@ParentAgentId";
parentParameter.Value = parentAgentId;
c.Parameters.Add(parentParameter);
using(DbDataReader r = c.ExecuteReader()) {
while(r.Read()) {
AgentEntry agent = new AgentEntry();
agent.ParentAgentId = parentAgentId;
agent.Id = r.GetInt32(0);
agent.Name = r.IsDBNull(1) ? "-" : r.GetString(1);
agent.Status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), r.GetString(2));
agents.Add(agent);
}
}
}
}
} finally {
rwLock.ExitReadLock();
}
return agents;
}
public byte[] GetAgentRawData(long id) {
rwLock.EnterReadLock();
try {
using(DbConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
using(DbCommand c = cnn.CreateCommand()) {
c.CommandText = "Select RawData from Agent where Id=@Id";
DbParameter idParameter = c.CreateParameter();
idParameter.ParameterName = "@Id";
idParameter.Value = id;
c.Parameters.Add(idParameter);
using(DbDataReader r = c.ExecuteReader()) {
if(r.HasRows) {
r.Read();
return (byte[])r.GetValue(0);
}
}
}
}
} finally {
rwLock.ExitReadLock();
}
return null; // agent with the given id not found
}
public ICollection GetResults(long agentId) {
List results = new List();
rwLock.EnterReadLock();
try {
using(DbConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
using(DbCommand c = cnn.CreateCommand()) {
c.CommandText = "Select Id, CreationTime, Summary, Description from Result where AgentId=@AgentId";
DbParameter agentParam = c.CreateParameter();
agentParam.ParameterName = "@AgentId";
agentParam.Value = agentId;
c.Parameters.Add(agentParam);
using(DbDataReader r = c.ExecuteReader()) {
while(r.Read()) {
ResultEntry result = new ResultEntry();
result.AgentId = agentId;
result.Id = r.GetInt32(0);
result.CreationTime = r.GetDateTime(1);
result.Summary = r.GetString(2);
result.Description = r.GetString(3);
results.Add(result);
}
}
}
}
} finally {
rwLock.ExitReadLock();
}
return results;
}
public ICollection GetSubResults(long resultId) {
List results = new List();
rwLock.EnterReadLock();
try {
using(DbConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
using(DbCommand c = cnn.CreateCommand()) {
c.CommandText = "Select Id, CreationTime, Summary, Description from Result where ParentResultId=@ParentResultId";
DbParameter parentParam = c.CreateParameter();
parentParam.ParameterName = "@ParentResultId";
parentParam.Value = resultId;
c.Parameters.Add(parentParam);
using(DbDataReader r = c.ExecuteReader()) {
while(r.Read()) {
ResultEntry result = new ResultEntry();
result.ParentResultId = resultId;
result.Id = r.GetInt32(0);
result.CreationTime = r.GetDateTime(1);
result.Summary = r.GetString(2);
result.Description = r.GetString(3);
results.Add(result);
}
}
}
}
} finally {
rwLock.ExitReadLock();
}
return results;
}
public byte[] GetResultRawData(long id) {
rwLock.EnterReadLock();
try {
using(DbConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
using(DbCommand c = cnn.CreateCommand()) {
c.CommandText = "Select RawData from Result where Id=@Id";
DbParameter idParameter = c.CreateParameter();
idParameter.ParameterName = "@Id";
idParameter.Value = id;
c.Parameters.Add(idParameter);
using(DbDataReader r = c.ExecuteReader()) {
if(r.HasRows) {
r.Read();
return (byte[])r.GetValue(0);
}
}
}
}
} finally {
rwLock.ExitReadLock();
}
return null; // result with the given id not found
}
public ICollection GetOperators() {
rwLock.EnterReadLock();
List operators = new List();
try {
using(DbConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
using(DbCommand c = cnn.CreateCommand()) {
c.CommandText = "Select id, name, rawdata from Operator";
using(DbDataReader r = c.ExecuteReader()) {
while(r.Read()) {
OperatorEntry op = new OperatorEntry();
op.Id = r.GetInt32(0);
op.Name = r.IsDBNull(1) ? "-" : r.GetString(1);
op.RawData = (byte[])r.GetValue(2);
operators.Add(op);
}
}
}
}
} finally {
rwLock.ExitReadLock();
}
return operators;
}
public OperatorEntry GetOperator(long id) {
rwLock.EnterReadLock();
try {
using(DbConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
using(DbCommand c = cnn.CreateCommand()) {
c.CommandText = "Select id, name, rawdata from Operator where id=@Id";
DbParameter idParam = c.CreateParameter();
idParam.ParameterName = "@Id";
idParam.Value = id;
c.Parameters.Add(idParam);
using(DbDataReader r = c.ExecuteReader()) {
r.Read();
OperatorEntry op = new OperatorEntry();
op.Id = r.GetInt32(0);
op.Name = r.IsDBNull(1) ? "-" : r.GetString(1);
op.RawData = (byte[])r.GetValue(2);
return op;
}
}
}
} finally {
rwLock.ExitReadLock();
}
}
#endregion
#region delete operator
public void DeleteOperator(long id) {
rwLock.EnterWriteLock();
try {
using(DbConnection cnn = new SQLiteConnection(connectionString)) {
cnn.Open();
using(DbTransaction t = cnn.BeginTransaction()) {
using(DbCommand c = cnn.CreateCommand()) {
c.Transaction = t;
c.CommandText = "Delete from Operator where id=@Id";
DbParameter idParam = c.CreateParameter();
idParam.ParameterName = "@Id";
idParam.Value = id;
c.Parameters.Add(idParam);
c.ExecuteNonQuery();
}
t.Commit();
}
}
} finally {
rwLock.ExitWriteLock();
}
}
#endregion
}
}