From 1adec35a6517b8861d4f791781b42ad60be61603 Mon Sep 17 00:00:00 2001 From: Nick Berardi Date: Sat, 17 Apr 2010 22:46:17 -0400 Subject: [PATCH] connections now are object oriented, and basic keyspace and column family support is being provided, see sandbox for example --- FluentCassandra.Sandbox/Program.cs | 55 ++++--- FluentCassandra/CassandraColumnFamily.cs | 106 ++++++++++++ ...amilyMap.cs => CassandraColumnFamily`1.cs} | 35 ++-- FluentCassandra/CassandraContext.cs | 110 +++++++++++++ FluentCassandra/CassandraDatabase.cs | 117 -------------- FluentCassandra/CassandraException.cs | 16 ++ FluentCassandra/CassandraKeyspace.cs | 134 +++++++++++++++ FluentCassandra/Connection/Connection.cs | 115 +++++++++++++ .../Connection/ConnectionBuilder.cs | 153 ++++++++++++++++++ .../Connection/ConnectionProvider.cs | 37 +++++ FluentCassandra/Connection/IConnection.cs | 20 +++ .../Connection/IConnectionProvider.cs | 18 +++ .../Connection/NormalConnectionProvider.cs | 41 +++++ FluentCassandra/Connection/Server.cs | 22 +++ FluentCassandra/FluentCassandra.csproj | 14 +- 15 files changed, 834 insertions(+), 159 deletions(-) create mode 100644 FluentCassandra/CassandraColumnFamily.cs rename FluentCassandra/{ColumnFamilyMap.cs => CassandraColumnFamily`1.cs} (58%) create mode 100644 FluentCassandra/CassandraContext.cs delete mode 100644 FluentCassandra/CassandraDatabase.cs create mode 100644 FluentCassandra/CassandraException.cs create mode 100644 FluentCassandra/CassandraKeyspace.cs create mode 100644 FluentCassandra/Connection/Connection.cs create mode 100644 FluentCassandra/Connection/ConnectionBuilder.cs create mode 100644 FluentCassandra/Connection/ConnectionProvider.cs create mode 100644 FluentCassandra/Connection/IConnection.cs create mode 100644 FluentCassandra/Connection/IConnectionProvider.cs create mode 100644 FluentCassandra/Connection/NormalConnectionProvider.cs create mode 100644 FluentCassandra/Connection/Server.cs diff --git a/FluentCassandra.Sandbox/Program.cs b/FluentCassandra.Sandbox/Program.cs index 1e758e6..fd6bee8 100644 --- a/FluentCassandra.Sandbox/Program.cs +++ b/FluentCassandra.Sandbox/Program.cs @@ -22,45 +22,44 @@ public class Location public string Name; } - public class LocationMap : ColumnFamilyMap { } - internal class Program { private static void Main(string[] args) { - CassandraDatabase.Init("Keyspace1"); - - CassandraConfiguration.Initialize(c => { - c.For(m => { - m.UseColumnFamily("Location"); - m.ForKey(p => p.Id); - m.ForProperty(p => p.Latitude); - m.ForProperty(p => p.Longitude); - m.ForProperty(p => p.Street); - m.ForProperty(p => p.City); - m.ForProperty(p => p.State); - m.ForProperty(p => p.PostalCode); - m.ForProperty(p => p.Name); + CassandraConfiguration.Initialize(config => { + config.For(x => { + x.UseColumnFamily("Location"); + x.ForKey(p => p.Id); + x.ForProperty(p => p.Latitude); + x.ForProperty(p => p.Longitude); + x.ForProperty(p => p.Street); + x.ForProperty(p => p.City); + x.ForProperty(p => p.State); + x.ForProperty(p => p.PostalCode); + x.ForProperty(p => p.Name); }); }); - var mapping = new LocationMap(); + using (var db = new CassandraContext("Keyspace1", "localhost")) + { + var location = new Location { + Id = "19001", + Name = "Some Location", - var location = new Location { - Id = "19001", - Name = "Some Location", + Latitude = 30.0M, + Longitude = -40.0M, - Latitude = 30.0M, - Longitude = -40.0M, + Street = "123 Some St.", + City = "Philadelphia", + State = "PA", + PostalCode = "19001" + }; - Street = "123 Some St.", - City = "Philadelphia", - State = "PA", - PostalCode = "19001" - }; + var table = db.GetColumnFamily(); - Console.WriteLine("Insert record"); - mapping.Insert(location); + Console.WriteLine("Insert record"); + table.Insert(location); + } Console.WriteLine("Done"); Console.Read(); diff --git a/FluentCassandra/CassandraColumnFamily.cs b/FluentCassandra/CassandraColumnFamily.cs new file mode 100644 index 0000000..c131fa9 --- /dev/null +++ b/FluentCassandra/CassandraColumnFamily.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Apache.Cassandra; + +namespace FluentCassandra +{ + public class CassandraColumnFamily + { + private CassandraKeyspace _keyspace; + private IConnection _connection; + + /// + /// + /// + /// + /// + public CassandraColumnFamily(CassandraKeyspace keyspace, IConnection connection) + { + _keyspace = keyspace; + _connection = connection; + } + + /// + /// + /// + /// + protected Cassandra.Client GetClient() + { + return _connection.Client; + } + + /// + /// + /// + /// + public void Insert(FluentColumnFamily record) + { + Insert(record.ColumnFamily, record.Key, record); + } + + /// + /// + /// + /// + /// + /// + public void Insert(string columnFamily, string key, FluentColumnFamily record) + { + var utf8 = Encoding.UTF8; + + foreach (var col in record) + { + var path = new ColumnPath { + Column_family = columnFamily, + Column = col.NameBytes + }; + + GetClient().insert( + _keyspace.KeyspaceName, + key, + path, + col.ValueBytes, + col.Timestamp.Ticks, + ConsistencyLevel.ONE + ); + } + } + + /// + /// + /// + /// + /// + public void Remove(FluentColumnFamily record, string columnName = null) + { + Remove(record.ColumnFamily, record.Key, columnName); + } + + /// + /// + /// + /// + /// + /// + public void Remove(string columnFamily, string key, string columnName = null) + { + var utf8 = Encoding.UTF8; + var path = new ColumnPath { + Column_family = columnFamily + }; + + if (!String.IsNullOrWhiteSpace(columnName)) + path.Column = FluentColumn.GetBytes(columnName); + + GetClient().remove( + _keyspace.KeyspaceName, + key, + path, + DateTimeOffset.UtcNow.Ticks, + ConsistencyLevel.ONE + ); + } + } +} diff --git a/FluentCassandra/ColumnFamilyMap.cs b/FluentCassandra/CassandraColumnFamily`1.cs similarity index 58% rename from FluentCassandra/ColumnFamilyMap.cs rename to FluentCassandra/CassandraColumnFamily`1.cs index e34dab1..e983427 100644 --- a/FluentCassandra/ColumnFamilyMap.cs +++ b/FluentCassandra/CassandraColumnFamily`1.cs @@ -10,16 +10,26 @@ namespace FluentCassandra { - public class ColumnFamilyMap + public class CassandraColumnFamily : CassandraColumnFamily { - private string _keyspace; private ITypeGetConfiguration _config; - public ColumnFamilyMap() + /// + /// + /// + /// + /// + public CassandraColumnFamily(CassandraKeyspace keyspace, IConnection connection) + : base(keyspace, connection) { _config = CassandraConfiguration.GetMapFor(); } + /// + /// + /// + /// + /// public FluentColumnFamily PrepareColumnFamily(T obj) { FluentColumnFamily record = new FluentColumnFamily(); @@ -37,21 +47,22 @@ public FluentColumnFamily PrepareColumnFamily(T obj) return record; } + /// + /// + /// + /// public void Insert(T obj) { - var record = PrepareColumnFamily(obj); - CassandraDatabase context = new CassandraDatabase(); - context.Open(); - context.Insert(record); - context.Close(); + Insert(PrepareColumnFamily(obj)); } + /// + /// + /// + /// public void Remove(T obj) { - CassandraDatabase context = new CassandraDatabase(); - context.Open(); - context.Remove(_config.ColumnFamily, _config.KeyMap.KeyAccessor(obj)); - context.Close(); + Remove(PrepareColumnFamily(obj)); } } } \ No newline at end of file diff --git a/FluentCassandra/CassandraContext.cs b/FluentCassandra/CassandraContext.cs new file mode 100644 index 0000000..d7f805e --- /dev/null +++ b/FluentCassandra/CassandraContext.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace FluentCassandra +{ + public class CassandraContext : IDisposable + { + private readonly ConnectionBuilder _connectionBuilder; + private readonly IConnectionProvider _connectionProvider; + private readonly IConnection _connection; + private readonly CassandraKeyspace _keyspace; + private bool _disposed; + + /// + /// + /// + /// + /// + /// + /// + /// + public CassandraContext(string keyspace, string host, int port = 9160, int timeout = 0, string provider = "Normal") + : this(new ConnectionBuilder(keyspace, host, port, timeout, provider)) { } + + /// + /// + /// + /// + public CassandraContext(string connectionString) + : this(new ConnectionBuilder(connectionString)) { } + + /// + /// + /// + /// + public CassandraContext(ConnectionBuilder connectionBuilder) + { + _connectionBuilder = connectionBuilder; + _connectionProvider = connectionBuilder.Provider; + _connection = _connectionProvider.Open(); + _keyspace = new CassandraKeyspace(_connectionBuilder.Keyspace, _connection); + } + + /// + /// Gets the database. + /// + public CassandraKeyspace Keyspace + { + get { return this._keyspace; } + } + + /// + /// Gets ConnectionProvider. + /// + public IConnectionProvider ConnectionProvider + { + get { return this._connectionProvider; } + } + + /// + /// + /// + public IConnection Connection + { + get { return this._connection; } + } + + /// + /// Gets a typed column family. + /// + /// Type of column family. + /// + public CassandraColumnFamily GetColumnFamily() + { + return _keyspace.GetColumnFamily(); + } + + /// + /// + /// + public void Dispose() + { + Dispose(true); + } + + /// + /// The dispose. + /// + /// + /// The disposing. + /// + protected virtual void Dispose(bool disposing) + { + if (!this._disposed && disposing && this._connection != null) + this._connectionProvider.Close(this._connection); + + this._disposed = true; + } + + /// + /// Finalizes an instance of the class. + /// + ~CassandraContext() + { + this.Dispose(false); + } + } +} \ No newline at end of file diff --git a/FluentCassandra/CassandraDatabase.cs b/FluentCassandra/CassandraDatabase.cs deleted file mode 100644 index 47185f7..0000000 --- a/FluentCassandra/CassandraDatabase.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Thrift.Transport; -using Thrift.Protocol; -using Apache.Cassandra; - -namespace FluentCassandra -{ - public class CassandraDatabase : IDisposable - { - private static string _initKeyspace; - private static string _initHost; - private static int _initPort; - - public static void Init(string keyspace, string host = "localhost", int port = 9160) - { - _initKeyspace = keyspace; - _initHost = host; - _initPort = port; - } - - private string _keyspace; - private string _host; - private int _port; - - private TTransport _transport; - private TProtocol _protocol; - private Cassandra.Client _client; - - public CassandraDatabase() - : this(_initKeyspace, _initHost, _initPort) { } - - public CassandraDatabase(string keyspace, string host = "localhost", int port = 9160) - { - _keyspace = keyspace; - _host = host; - _port = port; - - _transport = new TSocket(_host, _port); - _protocol = new TBinaryProtocol(_transport); - _client = new Cassandra.Client(_protocol); - } - - public void Open() - { - _transport.Open(); - } - - public void Close() - { - _transport.Close(); - } - - public void Insert(FluentColumnFamily record) - { - Insert(record.ColumnFamily, record.Key, record); - } - - public void Insert(string columnFamily, string key, FluentColumnFamily record) - { - var utf8 = Encoding.UTF8; - - foreach (var col in record) - { - var path = new ColumnPath { - Column_family = columnFamily, - Column = col.NameBytes - }; - - _client.insert( - _keyspace, - key, - path, - col.ValueBytes, - col.Timestamp.Ticks, - ConsistencyLevel.ONE - ); - } - } - - public void Remove(FluentColumnFamily record, string columnName = null) - { - Remove(record.ColumnFamily, record.Key, columnName); - } - - public void Remove(string columnFamily, string key, string columnName = null) - { - var utf8 = Encoding.UTF8; - var path = new ColumnPath { - Column_family = columnFamily - }; - - if (!String.IsNullOrWhiteSpace(columnName)) - path.Column = FluentColumn.GetBytes(columnName); - - _client.remove( - _keyspace, - key, - path, - DateTimeOffset.UtcNow.Ticks, - ConsistencyLevel.ONE - ); - } - - #region IDisposable Members - - public void Dispose() - { - if (_transport != null && _transport.IsOpen) - _transport.Close(); - } - - #endregion - } -} diff --git a/FluentCassandra/CassandraException.cs b/FluentCassandra/CassandraException.cs new file mode 100644 index 0000000..6a3f6cd --- /dev/null +++ b/FluentCassandra/CassandraException.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace FluentCassandra +{ + public class CassandraException : Exception + { + public CassandraException(string message) + : base(message) { } + + public CassandraException(string message, Exception innerException) + : base(message, innerException) { } + } +} diff --git a/FluentCassandra/CassandraKeyspace.cs b/FluentCassandra/CassandraKeyspace.cs new file mode 100644 index 0000000..e720f78 --- /dev/null +++ b/FluentCassandra/CassandraKeyspace.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Thrift.Transport; +using Thrift.Protocol; +using Apache.Cassandra; + +namespace FluentCassandra +{ + public class CassandraKeyspace + { + private readonly string _keyspaceName; + private readonly IConnection _connection; + + /// + /// + /// + /// + /// + public CassandraKeyspace(string keyspaceName, IConnection connecton) + { + _keyspaceName = keyspaceName; + _connection = connecton; + } + + /// + /// + /// + public IConnection Connection + { + get { return _connection; } + } + + /// + /// + /// + public string KeyspaceName + { + get { return _keyspaceName; } + } + + /// + /// + /// + /// + public CassandraColumnFamily GetColumnFamily() + { + return new CassandraColumnFamily(this, _connection); + } + + /// + /// Gets a typed column family. + /// + /// Type of column family. + /// + public CassandraColumnFamily GetColumnFamily() + { + return new CassandraColumnFamily(this, _connection); + } + + /// + /// + /// + /// + public void Insert(FluentColumnFamily record) + { + Insert(record.ColumnFamily, record.Key, record); + } + + /// + /// + /// + /// + /// + /// + public void Insert(string columnFamily, string key, FluentColumnFamily record) + { + var utf8 = Encoding.UTF8; + + foreach (var col in record) + { + var path = new ColumnPath { + Column_family = columnFamily, + Column = col.NameBytes + }; + + _connection.Client.insert( + _keyspaceName, + key, + path, + col.ValueBytes, + col.Timestamp.Ticks, + ConsistencyLevel.ONE + ); + } + } + + /// + /// + /// + /// + /// + public void Remove(FluentColumnFamily record, string columnName = null) + { + Remove(record.ColumnFamily, record.Key, columnName); + } + + /// + /// + /// + /// + /// + /// + public void Remove(string columnFamily, string key, string columnName = null) + { + var utf8 = Encoding.UTF8; + var path = new ColumnPath { + Column_family = columnFamily + }; + + if (!String.IsNullOrWhiteSpace(columnName)) + path.Column = FluentColumn.GetBytes(columnName); + + _connection.Client.remove( + _keyspaceName, + key, + path, + DateTimeOffset.UtcNow.Ticks, + ConsistencyLevel.ONE + ); + } + } +} diff --git a/FluentCassandra/Connection/Connection.cs b/FluentCassandra/Connection/Connection.cs new file mode 100644 index 0000000..ac3c08c --- /dev/null +++ b/FluentCassandra/Connection/Connection.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Thrift.Transport; +using Thrift.Protocol; +using Apache.Cassandra; + +namespace FluentCassandra +{ + public class Connection : IConnection, IDisposable + { + private ConnectionBuilder _builder; + private bool _disposed; + + private TTransport _transport; + private TProtocol _protocol; + private Cassandra.Client _client; + + /// + /// + /// + /// + internal Connection(ConnectionBuilder builder) + { + _builder = builder; + + Server = _builder.Servers.FirstOrDefault(); + + _transport = new TSocket(Server.Host, Server.Port, _builder.Timeout); + _protocol = new TBinaryProtocol(_transport); + _client = new Cassandra.Client(_protocol); + } + + /// + /// + /// + public string Keyspace + { + get { return _builder.Keyspace; } + } + + /// + /// + /// + public Server Server + { + get; + private set; + } + + /// + /// + /// + public bool IsOpen + { + get { return _transport.IsOpen; } + } + + /// + /// + /// + public void Open() + { + _transport.Open(); + } + + /// + /// + /// + public void Close() + { + _transport.Close(); + } + + /// + /// + /// + public Cassandra.Client Client + { + get { return _client; } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + } + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + if (_disposed) { + return; + } + + Close(); + _disposed = true; + } + + /// + /// Releases unmanaged resources and performs other cleanup operations before the + /// is reclaimed by garbage collection. + /// + ~Connection() + { + Dispose(false); + } + } +} diff --git a/FluentCassandra/Connection/ConnectionBuilder.cs b/FluentCassandra/Connection/ConnectionBuilder.cs new file mode 100644 index 0000000..ba1ea81 --- /dev/null +++ b/FluentCassandra/Connection/ConnectionBuilder.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace FluentCassandra +{ + public class ConnectionBuilder + { + /// + /// + /// + /// + /// + /// + /// + /// + public ConnectionBuilder(string keyspace, string host, int port = 9160, int timeout = 0, string provider = "Normal") + { + Keyspace = keyspace; + Servers = new List() { new Server(host, port) }; + Timeout = timeout; + Provider = GetConnectionProvider(provider); + } + + /// + /// + /// + /// + public ConnectionBuilder(string connectionString) + { + InitializeConnectionString(connectionString); + } + + /// + /// + /// + /// + private void InitializeConnectionString(string connectionString) + { + string[] connParts = connectionString.Split(';'); + IDictionary pairs = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + + foreach (string part in connParts) + { + string[] nameValue = part.Split(new[] { '=' }, 2); + + if (nameValue.Length != 2) + continue; + + pairs.Add(nameValue[0], nameValue[1]); + } + + #region Keyspace + + if (!pairs.ContainsKey("Keyspace")) + throw new CassandraException("Keyspace is required to create a connection"); + + Keyspace = pairs["Keyspace"]; + + #endregion + + #region Timeout + + if (!pairs.ContainsKey("Timeout")) + { + Timeout = 0; + } + else + { + int timeout; + if (!Int32.TryParse(pairs["Timeout"], out timeout)) + throw new CassandraException("Timeout is not valid."); + Timeout = timeout; + } + + #endregion + + #region Server + + Servers = new List(); + + if (!pairs.ContainsKey("Server")) + { + Servers.Add(new Server()); + } + else + { + string[] servers = pairs["Server"].Split(','); + foreach (var server in servers) + { + string[] serverParts = server.Split(':'); + string host = serverParts[0]; + + if (serverParts.Length == 2) + { + int port; + if (Int32.TryParse(serverParts[1], out port)) + Servers.Add(new Server(host, port)); + else + Servers.Add(new Server(host)); + } + else + Servers.Add(new Server(host)); + } + } + + #endregion + + #region Provider + + if (!pairs.ContainsKey("Provider")) + Provider = GetConnectionProvider("Normal"); + + #endregion + } + + /// + /// + /// + /// + /// + private IConnectionProvider GetConnectionProvider(string name) + { + switch (name.ToLower()) + { + case "normal": return new NormalConnectionProvider(this); + } + + throw new CassandraException("Cannot determine which connection provider should be used for " + name); + } + + /// + /// + /// + public string Keyspace { get; private set; } + + /// + /// + /// + public int Timeout { get; private set; } + + /// + /// + /// + public IList Servers { get; private set; } + + /// + /// + /// + public IConnectionProvider Provider { get; private set; } + } +} \ No newline at end of file diff --git a/FluentCassandra/Connection/ConnectionProvider.cs b/FluentCassandra/Connection/ConnectionProvider.cs new file mode 100644 index 0000000..89604ee --- /dev/null +++ b/FluentCassandra/Connection/ConnectionProvider.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace FluentCassandra +{ + public abstract class ConnectionProvider : IConnectionProvider + { + public abstract IConnection Open(); + public abstract bool Close(IConnection connection); + + /// + /// + /// + /// + protected ConnectionProvider(ConnectionBuilder builder) + { + Builder = builder; + } + + /// + /// + /// + public ConnectionBuilder Builder { get; private set; } + + /// + /// + /// + /// + public IConnection CreateNewConnection() + { + var conn = new Connection(Builder); + return conn; + } + } +} diff --git a/FluentCassandra/Connection/IConnection.cs b/FluentCassandra/Connection/IConnection.cs new file mode 100644 index 0000000..6a0c6d7 --- /dev/null +++ b/FluentCassandra/Connection/IConnection.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Apache.Cassandra; + +namespace FluentCassandra +{ + public interface IConnection : IDisposable + { + string Keyspace { get; } + Server Server { get; } + + Cassandra.Client Client { get; } + + bool IsOpen { get; } + void Open(); + void Close(); + } +} diff --git a/FluentCassandra/Connection/IConnectionProvider.cs b/FluentCassandra/Connection/IConnectionProvider.cs new file mode 100644 index 0000000..77b4cea --- /dev/null +++ b/FluentCassandra/Connection/IConnectionProvider.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace FluentCassandra +{ + public interface IConnectionProvider + { + ConnectionBuilder Builder { get; } + + IConnection CreateNewConnection(); + + IConnection Open(); + + bool Close(IConnection connection); + } +} diff --git a/FluentCassandra/Connection/NormalConnectionProvider.cs b/FluentCassandra/Connection/NormalConnectionProvider.cs new file mode 100644 index 0000000..7196fe7 --- /dev/null +++ b/FluentCassandra/Connection/NormalConnectionProvider.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace FluentCassandra +{ + public class NormalConnectionProvider : ConnectionProvider + { + /// + /// + /// + /// + public NormalConnectionProvider(ConnectionBuilder builder) + : base(builder) { } + + /// + /// + /// + /// + public override IConnection Open() + { + var conn = CreateNewConnection(); + conn.Open(); + return conn; + } + + /// + /// + /// + /// + /// + public override bool Close(IConnection connection) + { + if (connection.IsOpen) + connection.Dispose(); + + return true; + } + } +} diff --git a/FluentCassandra/Connection/Server.cs b/FluentCassandra/Connection/Server.cs new file mode 100644 index 0000000..846a500 --- /dev/null +++ b/FluentCassandra/Connection/Server.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Thrift.Transport; +using System.Net.Sockets; + +namespace FluentCassandra +{ + public class Server + { + public Server(string host = "127.0.0.1", int port = 9160) + { + Host = host; + Port = port; + } + + public int Port { get; private set; } + + public string Host { get; private set; } + } +} diff --git a/FluentCassandra/FluentCassandra.csproj b/FluentCassandra/FluentCassandra.csproj index 986ad93..5252247 100644 --- a/FluentCassandra/FluentCassandra.csproj +++ b/FluentCassandra/FluentCassandra.csproj @@ -74,8 +74,11 @@ - - + + + + + @@ -87,9 +90,16 @@ + + + + + + +