[smuxi] Engine(-Tests): initial SqliteMessageBuffer implementation (closes: #908)
- From: Mirco M. M. Bauer <mmmbauer src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [smuxi] Engine(-Tests): initial SqliteMessageBuffer implementation (closes: #908)
- Date: Fri, 28 Feb 2014 20:25:16 +0000 (UTC)
commit d43370523187518cbecb0595007eb16b9f098a83
Author: Mirco Bauer <meebey meebey net>
Date: Tue Feb 25 23:01:13 2014 +0100
Engine(-Tests): initial SqliteMessageBuffer implementation (closes: #908)
configure.ac | 4 +-
src/Engine-Tests/Engine-Tests.csproj | 1 +
src/Engine-Tests/SqliteMessageBufferTests.cs | 100 +++++++++++++
src/Engine/Engine.csproj | 1 +
src/Engine/Makefile.am | 3 +
src/Engine/MessageBuffers/SqliteMessageBuffer.cs | 172 ++++++++++++++++++++++
6 files changed, 280 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 09fe7a4..b5f6840 100644
--- a/configure.ac
+++ b/configure.ac
@@ -143,10 +143,12 @@ SHAMROCK_FIND_MONO_2_0_COMPILER_OR_HIGHER
SHAMROCK_CHECK_MONO_2_0_GAC_ASSEMBLIES([
System
System.Core
- System.Xml
+ System.Data
System.Runtime.Remoting
System.Runtime.Serialization
+ System.Xml
Mono.Posix
+ Mono.Data.Sqlite
])
PROFILE=debug
diff --git a/src/Engine-Tests/Engine-Tests.csproj b/src/Engine-Tests/Engine-Tests.csproj
index 040336f..1c30005 100644
--- a/src/Engine-Tests/Engine-Tests.csproj
+++ b/src/Engine-Tests/Engine-Tests.csproj
@@ -44,6 +44,7 @@
<Compile Include="GitMessageBufferTests.cs" />
<Compile Include="JsonMessageBufferTests.cs" />
<Compile Include="MessageDtoModelV1Tests.cs" />
+ <Compile Include="SqliteMessageBufferTests.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
diff --git a/src/Engine-Tests/SqliteMessageBufferTests.cs b/src/Engine-Tests/SqliteMessageBufferTests.cs
new file mode 100644
index 0000000..49be73e
--- /dev/null
+++ b/src/Engine-Tests/SqliteMessageBufferTests.cs
@@ -0,0 +1,100 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2014 Mirco Bauer <meebey meebey net>
+//
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+//
+// This program 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 2 of the License, or
+// (at your option) any later version.
+//
+// This program 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 this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+using NUnit.Framework;
+using Smuxi.Common;
+
+namespace Smuxi.Engine
+{
+ [TestFixture]
+ public class SqliteMessageBufferTests : MessageBufferTestsBase
+ {
+ protected override IMessageBuffer CreateBuffer()
+ {
+ var dbFile = Path.Combine(Platform.GetBuffersPath("testuser"),
+ "testprot");
+ dbFile = Path.Combine(dbFile, "testnet");
+ dbFile = Path.Combine(dbFile, "testchat.sqlite3");
+ if (File.Exists(dbFile)) {
+ File.Delete(dbFile);
+ }
+
+ return OpenBuffer();
+ }
+
+ protected override IMessageBuffer OpenBuffer()
+ {
+ return new SqliteMessageBuffer("testuser", "testprot", "testnet", "testchat");
+ }
+
+ [Test]
+ public void Reopen()
+ {
+ Buffer.Dispose();
+ OpenBuffer();
+ Enumerator();
+ }
+
+ [Test]
+ public void ImplicitFlush()
+ {
+ // generate 32 extra messsages to exceed the buffer size which
+ // forces a flush of the buffer to db4o
+ var bufferCount = Buffer.Count;
+ var msgs = new List<MessageModel>(Buffer);
+ for (int i = 1; i <= 32; i++) {
+ var builder = new MessageBuilder();
+ builder.AppendText("msg{0}", bufferCount + i);
+ var msg = builder.ToMessage();
+ msgs.Add(msg);
+ Buffer.Add(msg);
+ }
+
+ int j = 0;
+ foreach (var msg in Buffer) {
+ Assert.AreEqual(msgs[j++].ToString(), msg.ToString());
+ }
+ Assert.AreEqual(msgs.Count, j);
+ }
+
+ [Test]
+ public void ImplicitRemoveAt()
+ {
+ Buffer.MaxCapacity = 16;
+ // generate 32 extra messsages to exceed the max capacity which
+ // forces a RemoveAt() call of the oldest messages
+ var bufferCount = Buffer.Count;
+ var msgs = new List<MessageModel>(Buffer);
+ for (int i = 1; i <= 32; i++) {
+ var builder = new MessageBuilder();
+ builder.AppendText("msg{0}", bufferCount + i);
+ var msg = builder.ToMessage();
+ msgs.Add(msg);
+ Buffer.Add(msg);
+ }
+
+ Assert.AreEqual(Buffer.MaxCapacity, Buffer.Count);
+ Assert.AreEqual(msgs[19].ToString(), Buffer[0].ToString());
+ }
+ }
+}
diff --git a/src/Engine/Engine.csproj b/src/Engine/Engine.csproj
index 2c74ef3..ff441e0 100644
--- a/src/Engine/Engine.csproj
+++ b/src/Engine/Engine.csproj
@@ -112,6 +112,7 @@
<Compile Include="MessageBuffers\GitMessageBuffer.cs" />
<Compile Include="MessageBuffers\JsonMessageBuffer.cs" />
<Compile Include="Messages\Dto\MessageDtoModelV1.cs" />
+ <Compile Include="MessageBuffers\SqliteMessageBuffer.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Protocols\" />
diff --git a/src/Engine/Makefile.am b/src/Engine/Makefile.am
index 83183d1..e5a0719 100644
--- a/src/Engine/Makefile.am
+++ b/src/Engine/Makefile.am
@@ -67,6 +67,7 @@ FILES = \
MessageBuffers/ListMessageBuffer.cs \
MessageBuffers/MessageBufferBase.cs \
MessageBuffers/MessageBufferPersistencyType.cs \
+ MessageBuffers/SqliteMessageBuffer.cs \
Messages/FeedMessageBuilder.cs \
Messages/MessageBuilder.cs \
Messages/MessageModel.cs \
@@ -125,11 +126,13 @@ EXTRAS = \
REFERENCES = \
System \
System.Core \
+ System.Data \
System.Runtime.Remoting \
System.Runtime.Serialization \
System.Web \
System.Xml \
Mono.Posix \
+ Mono.Data.Sqlite \
$(NINI_LIBS) \
$(LOG4NET_LIBS) \
$(DB4O_LIBS) \
diff --git a/src/Engine/MessageBuffers/SqliteMessageBuffer.cs
b/src/Engine/MessageBuffers/SqliteMessageBuffer.cs
new file mode 100644
index 0000000..c8cc377
--- /dev/null
+++ b/src/Engine/MessageBuffers/SqliteMessageBuffer.cs
@@ -0,0 +1,172 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2014 Mirco Bauer <meebey meebey net>
+//
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+//
+// This program 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 2 of the License, or
+// (at your option) any later version.
+//
+// This program 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 this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.IO;
+using System.Text;
+using System.Linq;
+using System.Collections.Generic;
+using Mono.Data.Sqlite;
+using ServiceStack.Text;
+using Smuxi.Engine.Dto;
+
+namespace Smuxi.Engine
+{
+ public class SqliteMessageBuffer : MessageBufferBase
+ {
+#if LOG4NET
+ static readonly log4net.ILog f_Logger =
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+#endif
+ string DBPath { get; set; }
+ SqliteConnection Connection { get; set; }
+
+ public override int Count {
+ get {
+ var cmd = Connection.CreateCommand();
+ cmd.CommandText = "SELECT COUNT(*) FROM Messages";
+ return (int) Convert.ChangeType(cmd.ExecuteScalar(), typeof(int));
+ }
+ }
+
+ public override MessageModel this[int index] {
+ get {
+ return GetRange(index, 1).First();
+ }
+ set {
+ throw new NotImplementedException();
+ }
+ }
+
+ public SqliteMessageBuffer(string sessionUsername, string protocol,
+ string networkId, string chatId) :
+ base(sessionUsername, protocol, networkId, chatId)
+ {
+ DBPath = GetBufferPath() + ".sqlite3";
+ Connection = new SqliteConnection("URI=file:" + DBPath);
+ Connection.Open();
+
+ var sql = "CREATE TABLE IF NOT EXISTS Messages (" +
+ "ID INTEGER PRIMARY KEY," +
+ "JSON TEXT" +
+ ")";
+ var cmd = Connection.CreateCommand();
+ cmd.CommandText = sql;
+ cmd.ExecuteNonQuery();
+ }
+
+ public override void Add(MessageModel msg)
+ {
+ if (msg == null) {
+ throw new ArgumentNullException("msg");
+ }
+
+ var dto = new MessageDtoModelV1(msg);
+ var json = JsonSerializer.SerializeToString(dto);
+
+ var cmd = Connection.CreateCommand();
+ cmd.CommandText = "INSERT INTO Messages (JSON)" +
+ " VALUES(@json)";
+ var param = cmd.CreateParameter();
+ param.ParameterName = "json";
+ param.Value = json;
+ cmd.Parameters.Add(param);
+
+ cmd.ExecuteNonQuery();
+ }
+
+ public override IList<MessageModel> GetRange(int offset, int limit)
+ {
+ using (var cmd = Connection.CreateCommand()) {
+ cmd.CommandText = "SELECT ID, JSON FROM Messages " +
+ " ORDER BY ID" +
+ " LIMIT @limit OFFSET @offset ";
+ var param = cmd.CreateParameter();
+ param.ParameterName = "offset";
+ param.Value = offset.ToString();
+ cmd.Parameters.Add(param);
+
+ param = cmd.CreateParameter();
+ param.ParameterName = "limit";
+ param.Value = limit.ToString();
+ cmd.Parameters.Add(param);
+
+ var reader = cmd.ExecuteReader();
+ var msgs = new List<MessageModel>(limit);
+ while (reader.Read()) {
+ var json = (string) reader["JSON"];
+ var dto = JsonSerializer.DeserializeFromString<MessageDtoModelV1>(json);
+ var msg = dto.ToMessage();
+ msgs.Add(msg);
+ }
+ return msgs;
+ }
+ }
+
+ public override void Clear()
+ {
+ var cmd = Connection.CreateCommand();
+ cmd.CommandText = "DELETE FROM Messages";
+ cmd.ExecuteNonQuery();
+ }
+
+ public override bool Contains(MessageModel item)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override void CopyTo(MessageModel[] array, int arrayIndex)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override bool Remove(MessageModel item)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override IEnumerator<MessageModel> GetEnumerator()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override int IndexOf(MessageModel item)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override void Insert(int index, MessageModel item)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override void RemoveAt(int index)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override void Flush()
+ {
+ }
+
+ public override void Dispose()
+ {
+ Flush();
+ }
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]