Giter VIP home page Giter VIP logo

fluentcassandra's Introduction

FluentCassandra

FluentCassandra is a .NET library for accessing Apache Cassandra. It fully impliments all commands that can be issued against the Apache Cassandra interface and supports .NET 4.0 dynamic keyword as well as a LINQ like expressions for querying the database. The goal of this project is to keep the interface in sync with the latest version of Cassandra and make it as easy as possible for .NET developers to start, adopt and program against the Cassandra database.

Getting Help

You can get help with FluentCassandra by asking questions or starting a discussion on our group. https://groups.google.com/d/forum/fluentcassandra

Installing Cassandra

Taken from the "Cassandra Jump Start For Windows" by Nick Berardi:

  1. Download Cassandra from http://cassandra.apache.org/

  2. Extract Cassandra to a directory of your choice (I used c:\development\cassandra)

  3. Set the following environment variables

    JAVA_HOME (To the directory where you install the JRE, this should not be the bin directory)
    CASSANDRA_HOME (To the directory you extracted the files to in step 1)
    

    Please note that you are going to want to be running Java JRE 6 for running Cassandra.

  4. Modify your Cassandra config file as you like and don't forget to update the directory locations from a UNIX like path to something on your windows directory (in my example the config file is located at c:\development\cassandra\conf\storage-conf.xml)

  5. Open cmd and run the cassandra.bat file (in my example the batch file is located at c:\development\cassandra\bin\cassandra.bat)

    cd c:\development\cassandra\bin\
    .\cassandra.bat
    
  6. You can verify that Cassandra is running, by trying to connect to the server. To do this open a new cmd and run the cassandra-cli.bat file from the bin directory.

    cd c:\development\cassandra\bin\
    .\cassandra-cli.bat
    connect localhost/9160
    

Your First Fluent Cassandra Application

There was an indepth 2 part series of blog posts made on the subject of creating your first Fluent Cassandra application.

  1. Your First Fluent Cassandra Application
  2. Your First Fluent Cassandra Application (part 2)

Building FluentCassandra

If you need to build FluentCassandra locally, know that FluentCassandra uses Albacore - a Ruby-based build system for Windows.

To build FluentCassandra, install Ruby onto your machine and then open a new command prompt to your local FluentCassandra directory and execute the following command:

$: rake

And that's it! The build will automatically run for you. You can also execute rake -T to see a list of additional commands.

fluentcassandra's People

Contributors

aaronontheweb avatar bjuris avatar caldas avatar clamanna avatar derekliang avatar dlbromen avatar edweip3 avatar eplowe avatar gillotte avatar kellabyte avatar mkeats avatar nathannis avatar nberardi avatar rsparkyc avatar sdether avatar sonofsatoshi avatar ssteo1156 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fluentcassandra's Issues

Followed the First Fluent Cassandra example, but not get through

Hello @nberardi

I followed "Your First Fluent Cassandra" example, with some modification (the article is creating a super-column, but I only need column), but it gave an exception of Apache.Cassandra.Unavailable.

It seems the updating is fine, but the exception was given when I try to read(key) after a update.

Could you please have a look at my simple class file? I am using Cassandra 1.0.6 by the way.

Thanks

public class CassandraAPI
{
    private CassandraContext cassandraDB;
    private CassandraColumnFamily<BytesType> family;
    public CassandraAPI()
    {
        cassandraDB = new CassandraContext(keyspace: "MyKeyspace", host: "192.168.178.32");
        family = cassandraDB.GetColumnFamily<BytesType>("ColumnFamilyName");

    }

    public void update(byte[] key1, byte[] value)
    {
        dynamic post = family.CreateRecord(key: key1);
        post.value = value;
        // attach the post to the database
        Console.WriteLine("attaching record");
        cassandraDB.Attach(post);

        // save the changes
        Console.WriteLine("saving changes");
        cassandraDB.SaveChanges();
    }

    public void read(byte[] key)
    {
        dynamic getPost = family.Get(key).FirstOrDefault();
        Console.WriteLine("getPost");
        byte[] value = getPost.value;
        Console.WriteLine(value.Length);
    }


}

This is really confusing me...

I have this problem with using Fluent Cassandra in a test application. All I want to do was set the IsOnline field to true inside the SignIn method, but I keep getting the exception "supercolumn parameter is not optional for super CF". I tried everything, but I can't seem to get it to work. All the data is created and inserted into my Cassandra Keyspace, but to change it again to IsOnline after insertion is failing me.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using FluentCassandra;
using FluentCassandra.Connections;
using FluentCassandra.Types;
using FluentCassandra.Operations;
using FluentCassandra.ObjectSerializer;
using FluentCassandra.Linq;

namespace CassandraTryTwo
{
    class Program
    {
        private static void CreateDatabase()
        {
            using (var context = new CassandraContext(keyspace: "RadiumNet", host: "localhost"))
            {
                if (context.KeyspaceExists("RadiumNet"))
                {
                    context.DropKeyspace("RadiumNet");
                }

                var keyspace = new CassandraKeyspace("RadiumNet", context);

                keyspace.TryCreateSelf();
                keyspace.TryCreateColumnFamily(
                    new CassandraColumnFamilySchema
                    {
                        FamilyName = "Accounts",
                        FamilyType = ColumnType.Super,
                        KeyValueType = CassandraType.UTF8Type,
                        SuperColumnNameType = CassandraType.UTF8Type,
                        ColumnNameType = CassandraType.UTF8Type,
                        DefaultColumnValueType = CassandraType.UTF8Type
                    }
                );
            }

            return;
        }

        private static void SignUp(String email, String password, String name, String surname, String age)
        {
            using (var context = new CassandraContext(keyspace: "RadiumNet", host: "localhost"))
            {
                var accountFamily = context.GetSuperColumnFamily("Accounts");
                var accountColumn = accountFamily.Get(email).First();

                if (accountColumn.Count() > 0)
                {
                    Console.WriteLine("User {0} already registered", email);
                }
                else
                {
                    dynamic account = accountColumn;

                    account = accountFamily.CreateRecord(key: email);

                    dynamic details = account.CreateSuperColumn();
                    details.Password = password;
                    details.Name = name;
                    details.Surname = surname;
                    details.Age = age;

                    dynamic flags = account.CreateSuperColumn();
                    flags.IsBlocked = "False";
                    flags.IsBanned = "False";
                    flags.IsOnline = "False";

                    account.Details = details;
                    account.Flags = flags;

                    context.Attach(account);
                    context.SaveChanges();
                }
            }

            return;
        }

        private static void SignIn(String email, String password)
        {
            using (var context = new CassandraContext(keyspace: "RadiumNet", host: "localhost"))
            {
                var accountFamily = context.GetSuperColumnFamily("Accounts");
                var accountColumn = accountFamily.Get(email).First();

                if (accountColumn.Count() == 0)
                {
                    Console.WriteLine("User {0} did not register", email);
                }
                else
                {
                    dynamic account = accountColumn;
                    dynamic details = account.Details;
                    dynamic flags = account.Flags;

                    if (details.Password != password)
                    {
                        Console.WriteLine("User {0} provided an invalid password", email);
                    }
                    else
                    {
                        flags.IsOnline = "True";

                        Console.WriteLine("Welcome {0} {1}", details.Name, details.Surname);

                        context.Attach(account);
                        context.SaveChanges();
                    }
                }
            }

            return;
        }

        private static void SetupConsole()
        {
            Console.Title = "Cassandra Test";
            Console.ForegroundColor = ConsoleColor.White;
            Console.BackgroundColor = ConsoleColor.Black;

            Console.SetWindowSize(120, 40);
            Console.Clear();
        }

        private static void Pause()
        {
            Console.WriteLine();
            Console.WriteLine("Press ENTER to continue...");
            Console.ReadLine();
        }

        private static void Main(string[] args)
        {
            SetupConsole();

            CreateDatabase();

            SignUp("[email protected]", "BooBab", "Wynand", "Pieterse", "22");
            SignUp("[email protected]", "GreenBab", "Henk", "Pieterse", "27");

            SignIn("[email protected]", "BooBab");
            SignIn("[email protected]", "Grrr");
            SignIn("[email protected]", "Breezer");

            Pause();
        }
    }
}

Linq .Count() support

It seems that Linq.Count is not supported in FluentCassandra

var cnt = (from u in _db.GetColumnFamily("test") select u).Count();

throws:
CassandraColumnFamily+QueryProvider.cs (137) TElement' must inherit from IFluentBaseColumnFamily

Multiple CQL Commands Per Request

FluentCassandra.Operations.CassandraOperationException was caught
Message=line 1:1095 mismatched input 'UPDATE' expecting EOF
Source=FluentCassandra
StackTrace:
at FluentCassandra.CassandraSession.ExecuteOperation[TResult](Operation1 action, Nullable1 throwOnError)
at FluentCassandra.CassandraContext.ExecuteOperation[TResult](Operation1 action, Nullable1 throwOnError)
at FluentCassandra.CassandraContext.ExecuteQuery(UTF8Type cqlQuery)
at GitHub.Cassandra.EventMigration.Program.WriteEvents(Event[] events) in C:\Work\Code\GitHub.Cassandra.EventMigration\GitHub.Cassandra.EventMigration\Program.cs:line 194
InnerException: Apache.Cassandra.InvalidRequestException
Message=Exception of type 'Apache.Cassandra.InvalidRequestException' was thrown.
Source=FluentCassandra
Why=line 1:1095 mismatched input 'UPDATE' expecting EOF
StackTrace:
at Apache.Cassandra.Cassandra.Client.recv_execute_cql_query()
at Apache.Cassandra.Cassandra.Client.execute_cql_query(Byte[] query, Compression compression)
at FluentCassandra.Operations.CassandraClientWrapper.execute_cql_query(Byte[] query, Compression compression)
at FluentCassandra.Operations.ExecuteCqlQuery.Execute()
at FluentCassandra.Operations.Operation`1.TryExecute(TResult& result)
InnerException:

"Error deflating query string." when using CQL.

There seems to be an issue when you create an instance of CassandraContext() using a single ConnectionString parameter. After doing this if you call ExecuteQuery() passing in some CQL an error of "Error deflating query string." is returned. See example below.

        using (CassandraContext db = new CassandraContext("Keyspace=JeffSTest;Server=10.15.10.70"))
        {
            var rows = db.ExecuteQuery("SELECT * FROM TestCF");
        }

What's interesting is if you create a CassandraContext() passing in the Keyspace and Server as separate parameters then everything works as intended. See example below.

        using (CassandraContext db = new CassandraContext("JeffSTest", new Server("10.15.10.70")))
        {
            var rows = db.ExecuteQuery("SELECT * FROM TestCF");
        }

replication_factor not working in Cassandra 1.1.0

var keyspace = new CassandraKeyspace(new CassandraKeyspaceSchema
                                                    {
                                                        Name = KeyspaceName,
                                                        Strategy = CassandraKeyspaceSchema.ReplicaPlacementStrategySimple,
                                                        ReplicationFactor = 1
                                                    }, db);

Throw and error:

FluentCassandra.Operations.CassandraOperationException: SimpleStrategy requires a replication_factor strategy option. ---> Apache.Cassandra.InvalidRequestException: Exception of type 'Apache.Cassandra.InvalidRequestException' was thrown.

I'm using the 1.1.0 release of Cassandra - presumably something changed and it's not happy with the replication factor value there?

Clear _trackers after db.SaveChanges()

In the method CassandraContext.SaveChanges(), after saving the changes, you only clear the trackers in _trackers. Why don't you clear the _trackers it self ?

When the size of _trackers is big, Attach() and SaveChanges() will consume very much time...

Decimal Issues

So I created a table with a default_validation of type decimal. When I use a CQL statement to insert a new column and then attempt to read that column back out, FluentCassandra throws an exception why trying to convert the byte array to a decimal. The exception happens in BytesTypeConvert.ToDecimal().

It seems that the way CQL converts a decimal to a byte array is different then how Fluent is doing it. The length of the byte array varies in size based on the size of the decimal value. It's possible there's a bug in CQL or I'm not representing the decimal correctly in CQL syntax, though I couldn't find anything on DataStax website about this. Below was the CQL I was using.

CREATE TABLE OfferReservation (KEY text PRIMARY KEY) WITH comparator = text AND default_validation = decimal

INSERT INTO OfferReservation (KEY, 'MyColumn') VALUES ('Key1', 0.25)
INSERT INTO OfferReservation (KEY, 'MyColumn') VALUES ('Key2', 2000000000000.1234)

GuidGenerator.GenerateTimeBasedGuid() can create duplicate Time-based UUIDs

In a tight loop GuidGenerator.GenerateTimeBasedGuid() will generate duplicate guids. When using these guids for column names, values could potentially be overwritten.

I'm working on a fix based on code from a java project (http://johannburkard.de/software/uuid/) which is used in Hector (a Java client for Cassandra). Basically, it keeps track of the ticks used for the previously generated guid, if the next guid would use the same (or earlier) ticks value, the value would be incremented by 1, stored as the last used value, and then the new guid would be generated. I think (at least hope) the code will be clearer.

Linq2CQL3 and pagination support

In CQL3 token() construction is now supported (see http://www.datastax.com/dev/blog/cql3-evolutions).

E.g.: select * from example_table where token(id) > token(2);

This construction is provided mostly for pagination. In current version of FluentCassandra it is not supported. I can imagaine that it works like this (if partitionKey is an integer):
(from u in _db.GetColumnFamily("example_table") select u).Skip(10001);
or it can require a special treatment of PartitionKey in Where() clause:
from u in _db.GetColumnFamily("example_table") where TokenComparator.GreaterThan(u["idx"],10001) select u;

Connection Pool Not Releasing Connections

Description: in PooledConnectionProvider.cs _usedConnections is being filled up (100) and not being released.

Usage (my code):

var builder = new ConnectionBuilder(
                keyspace: ConfigurationManager.AppSettings["keyspace"],
                host: ConfigurationManager.AppSettings["CassandraServer"],
                pooling: true);

using (var db = new CassandraContext(ConnectionBuilder()))
            {
                var family = db.GetColumnFamily("Qdex");

                dynamic c = family.Get(sequence).FirstOrDefault();

                foreach (dynamic line in c)
                {
                    lines.Add(Serializer.Deserialize<QdexLine>(line.ColumnValue));
                }

                return lines.AsQueryable<QdexLine>();
            }

in MultiGetColumnFamilySlice.Execute() (comments added)

// This line calls CreateConnection() and Close()
// in PooledConnectionProvider
var schema = ColumnFamily.GetSchema();

            var parent = new CassandraColumnParent {
                ColumnFamily = ColumnFamily.FamilyName
            };

            SlicePredicate = Helper.SetSchemaForSlicePredicate(SlicePredicate, schema);

            Dictionary<byte[], List<Apache.Cassandra.ColumnOrSuperColumn>> output = null;
            try
            {
                 // This line calls CreateConnection() in PooledConnectionProvider
                 // Close() is never called
                 output = Session.GetClient().multiget_slice(
                    Keys,
                    parent,
                    SlicePredicate,
                    Session.ReadConsistency
                );
            }

Issues with Selecting Deleted (tombstoned) Columns

So I deleted a column from a row and then attempted to do a select for that column on that row and FluentCassandra threw an exception. From my understanding, when a column is "deleted" in Cassandra it's actually marked as tombstoned and technically still exits until garbage collection hits. However, it's value is set to NULL. When you attempt to select that column Cassandra actually returns the column with a null value. FluentCassandra then attempts to convert that value to the appropriate datatype but blows up because the byte array is null.

I'm not sure what the best way to handle this is but I'm thinking that if the column is returned with a NULL value then FluentCassandra should treat it as if it doesn't exist and skip trying to add it to the columns collection for that row.

I was doing all of my commands using CQL. The data type for the column name was text and for the value it was float.

Problem with GuidGenerator on AsParallel context

Hi man, here is the code that I´m testing:

static void Main(string[] args)
{
    List<Int32> list = new List<Int32>();
    for (int i = 0; i < 5; i++)
    {
        list.Add(i);
    }
    list.AsParallel().ForAll(item => X());
}

static void X()
{
Guid rowGuid = GuidGenerator.GenerateTimeBasedGuid();
//Here I get a cassandra client 
//Insert cassandra row column name 'A' just for test
}

Because of parallel I just insert 2 or 3 items instead of 5.

incorrect mutation being set on super column

In the FluentSuperColumn class, the function UpdateParent is calling ResetMutationAndAddAllColumns(). This causes mutations to be added to the tracker for all columns in an existing super column. ResetMutation() should probably be called instead.

steps to reproduce:

  1. Create a super column family.
  2. insert a row with a super column.
  3. update the row to add more super columns using code similar to below

var family = db.GetSuperColumnFamily(ColumnFamilyName);
var record = family.Get(id).FirstOrDefault();

dynamic column = record.CreateSuperColumn();
column.columnname = "column value";
record["supercolumn key"] = column;

db.Attach(record);
db.SaveChanges();

not clear if record.TrySetColumn() is a valid way to set a named column

Take this code:

            IEnumerable<string> listOfColNames = new [] { "abc", "cba", "xxx" };

            var record = family.CreateRecord(123);

            foreach(var col in listOfColNames)
                record.TrySetColumn(col, "aa");

Is it a correct way to set named columns this way? The "Try" prefix on the method doesn't encourage trust that this is a legal API to use for this purpose.

Tests failing in GuidGeneratorTest fixture

On the master branch two of the tests are failing:

FluentCassandra.GuidGeneratorTest.GetDateTimeLocal

System.ArgumentException : The UTC Offset of the local dateTime parameter does not match the offset argument.
Parameter name: offset

at System.DateTimeOffset..ctor(DateTime dateTime, TimeSpan offset)
at FluentCassandra.GuidGenerator.GenerateTimeBasedGuid(DateTime dateTime, Byte[] node) in GuidGenerator.cs: line 95
at FluentCassandra.GuidGenerator.GenerateTimeBasedGuid(DateTime dateTime) in GuidGenerator.cs: line 84
at FluentCassandra.GuidGeneratorTest.GetDateTimeLocal() in GuidGeneratorTest.cs: line 57

FluentCassandra.GuidGeneratorTest.GetDateTimeUnspecified

Expected: 1980-03-14 12:23:42.112
But was:  1980-03-14 11:23:42.112

at NUnit.Framework.Assert.That(Object actual, IResolveConstraint expression, String message, Object[] args)
at FluentCassandra.GuidGeneratorTest.GetDateTimeUnspecified() in GuidGeneratorTest.cs: line 49

I will investigate and if I can resolve the problem then I'll submit a fix.

Expose Time Helper Methods

I was wondering if the following methods could be made public. There are a few use cases where it would be helpful to be able to switch back and for between a timestamp in my own code. An example is when you want to set an explicit timestamp on a column when using a CQL query.

FluentCassandra.Operations.Helper.ToTimestamp()
FluentCassandra.Operations.Helper.FromTimestamp()

I think it would also be useful to expose the UnixStart field as public.

Currently the Helper class in marked as internal. I do NOT think it makes sense to make the whole class public. Maybe there's a better location to make these helper type methods to be public? Maybe they could be made into public extension methods.

In a get column slicing, schema omitted in some instances with Helper.ConvertColumnToFluentColumn

I discovered what I believe is a bug while working with the cf.GetSingle method. Thankfully it seems to be a trivial fix which I propose below

This seems to cause the unnecessary byte reversing of text fields, and other issues I'm sure. The schema is in context of the operating method but simply isn't passed to the helper class

  \src\Operations\GetColumnFamilyIndexedSlices.cs(40): return Helper.ConvertColumnToFluentColumn(col.Column);
  \src\Operations\GetColumnFamilyRangeSlices.cs(36): return Helper.ConvertColumnToFluentColumn(col.Column);
  \src\Operations\GetColumnFamilySlice.cs(46):  var r = Helper.ConvertColumnToFluentColumn(result.Column);

I believe should be

  \src\Operations\GetColumnFamilyIndexedSlices.cs(40): return Helper.ConvertColumnToFluentColumn(col.Column, schema);
  \src\Operations\GetColumnFamilyRangeSlices.cs(36): return Helper.ConvertColumnToFluentColumn(col.Column, schema);
  \src\Operations\GetColumnFamilySlice.cs(46):  var r = Helper.ConvertColumnToFluentColumn(result.Column, schema);

TimeStamp should be switched to Microseconds

So I ran into an issue last week were when using a CQL statement to insert a column, letting it implicitly set the TimeStamp, it's using Microseconds. From what I see, FluentCassandra is using Milliseconds and when it tries to read this out of the database it throws an exception. I see you add some code recently to sort of handle this but I don't think the implementation is flawless. As you get closer to 1970 the timestamp will be incorrect because it will no longer divide by 1000 and then start assuming that the value represents Milliseconds instead of Microseconds. Also, using reflection, the AddMilliseconds() method on the DateTimeOffset object with throw an exception if the value to add is greater than 315537897600000.

My understanding is that in the past Milliseconds was the recommended way to store TimeStamps in Cassandra. However, it now seems that the recommendation is to use Microseconds because of it's greater precision. I have been chatting with Matt Denis over at DataStax and he said that most people are switching to Microseconds and that this is also his recommendation.

I propose that FluentCassandra switch to Microseconds as it's default but allow for a config option (as part of the connection string) to indicate the default timestamp storage precision. This way anyone that is currently using Milliseconds can still function but those of us just starting out can start using Microseconds. (Alternatively the default could be Milliseconds for backwards compatibility, with an option to switch to Microseconds).

From my research the best way to calculate Microseconds in .Net is to use Ticks divided by 10. 1 Tick represents 100 Nanoseconds.

Plan to support 0.8?

With Cassandra 0.8 on feature freeze (rc1 under vote right now). Are there any plans to support it?

Consistency Levels / ConnectionBuilder

Hi, absolutely love the project and would be interested in contributing on bugs/performance if our usage of Cassandra takes off!

One area which is a bit grey to me at the moment is how to specify the Consistency Levels for both reads and writes. Is this set at creation of the CassandraContext time or per SaveChanges() call?

I'm guessing its the former and these are to be exposed as part of ConnectionBuilder, but haven't been able to find a clue in the source as to how you might be thinking this should be done.

Have you any advice?

Cheers.

unable to set cql version at the context level

I'm trying to create a table with a composite type key using the syntax similar to

CREATE TABLE seen_ships (
day text,
time_seen timestamp,
shipname text,
PRIMARY KEY (day, time_seen)
);

as explained on http://www.datastax.com/dev/blog/whats-new-in-cql-3-0

getting this snippet to work requires being able to set the CQL version to 3.0.0

        using (var db = new CassandraContext(keyspace: KeyspaceName, server: Server))
        {                
            db.ExecuteNonQuery(@"CREATE TABLE seen_ships (
                day text,
                time_seen timestamp,
                shipname text,
                PRIMARY KEY (day, time_seen)
            );");
        }

I saw some code that has the functionality partially plummed to set the cql version. So I did a dirty hack for my self, I wouldn't mind flushing it out it if I knew the convention you wished to use.

UnavailableException is thrown when getting row

Hi nberardi,

Here is my situation:

  • My app creates a new keyspace called "PhoneEnrichmentDb", insert keys & rows well.
  • Drop that keyspace using cassandra-cli.
  • Run the app to create keyspace again.
  • It thrown exception when retrieving row (ex: FluentColumnFamily currentHouse = houseColumnFamily.Get("2172033018").First();
    But I can use cassandra-cli to retrieve that key:
    [default@PhoneEnrichmentDb] get Houses['2172033018'];
    Cassandra returns without exception:
    Returned 0 results.

Here are my stack trace:
(my code) FluentColumnFamily currentHouse = houseColumnFamily.Get("2172033018").First();

FluentCassandra.dll!FluentCassandra.Operations.MultiGetColumnFamilySlice.Execute() Line 26 + 0xb8 bytes
==> var output = Session.GetClient().multiget_slice(
Keys,
parent,
SlicePredicate,
Session.ReadConsistency
);

FluentCassandra.dll!FluentCassandra.Operations.CassandraClientWrapper.multiget_slice(System.Collections.Generic.List<FluentCassandra.Types.CassandraObject> keys, FluentCassandra.Operations.CassandraColumnParent column_parent, FluentCassandra.Operations.CassandraSlicePredicate predicate, Apache.Cassandra.ConsistencyLevel consistency_level) Line 55 + 0x3f bytes
==> return _client.multiget_slice(
Helper.ToByteArrayList(keys),
Helper.CreateColumnParent(column_parent),
Helper.CreateSlicePredicate(predicate),
consistency_level);

FluentCassandra.dll!Apache.Cassandra.Cassandra.Client.multiget_slice(System.Collections.Generic.List<byte[]> keys, Apache.Cassandra.ColumnParent column_parent, Apache.Cassandra.SlicePredicate predicate, Apache.Cassandra.ConsistencyLevel consistency_level) Line 292 + 0x8 bytes
==> return recv_multiget_slice();

FluentCassandra.dll!Apache.Cassandra.Cassandra.Client.recv_multiget_slice() Line 326
==> if (result.__isset.ue) {
throw result.Ue; ==> exception is thrown here

Thank you very much if you could help to find the reason.

Best regards
Yuki

Issue running ExecuteNonQuery

I'm trying to create some secondary indexes like they do in the example here: http://www.datastax.com/docs/1.0/ddl/indexes

The only way I've found to be able to attempt to do is this by running this:

    db.ExecuteNonQuery(@"create column family users with comparator=UTF8Type
     and column_metadata=[{column_name: full_name, validation_class: UTF8Type},
     {column_name: email, validation_class: UTF8Type},
     {column_name: birth_year, validation_class: LongType, index_type: KEYS},
     {column_name: state, validation_class:  UTF8Type, index_type: KEYS}];");

However, I'm getting the following error:
no viable alternative at character ']'

What am I doing wrong?

Divide by zero in DateTimePrecise

I'm seeing a divide by zero exception in FluentCassandra 1.1.3 with the following call stack:

System.DivideByZeroException: Attempted to divide by zero.
at System.DateTimePrecise.GetUtcNow() in C:\FluentCassandra\V1.1.3\src\System\DateTimePrecise.cs:line 82
at FluentCassandra.FluentColumn..ctor(CassandraColumnSchema schema) in C:\FluentCassandra\V1.1.3\src\FluentColumn.cs:line 33
at FluentCassandra.FluentColumnFamily.TrySetColumn(Object name, Object value) in C:\FluentCassandra\V1.1.3\src\FluentColumnFamily.cs:line 235

This points to the following line in DateTimePrecise.GetUtcNow():

    DateTime tBaseNew = immutable.BaseTime.AddTicks(((
                    stopWatchTicks - immutable.ObservedTicks) * ClockTickFrequency) / (
                        immutable.StopWatchFrequency));

I can see only 2 places where an instance of DateTimePreciseSafeImmutable is created:

  1. In the constructor of DateTimePrecise, where Stopwatch.Frequency is assigned to StopWatchFrequency.
    I've written a tiny test program to dump Stopwatch.Frequency to the console and it's not zero on the same box.
  2. At the end of DateTimePrecise.GetUtcNow(), which has this in the denominator:
    utc.Ticks - immutable.ObservedTime.Ticks + utc.Ticks + utc.Ticks - tBaseNew.Ticks - immutable.ObservedTime.Ticks

When does this become zero?

P.S. If this expression is correct, then barring overflow issues, it can be simplified to:

    3 * utc.Ticks - 2 * immutable.ObservedTime.Ticks - tBaseNew.Ticks

family.CreateRecord(key: key) doesnt check if BytesType is of 0 length

Take for example this code:

            var family = db.GetColumnFamily<UTF8Type>("report_word_index");

            dynamic record1 = family.CreateRecord("");
            record1.x = 1;
            db.Attach(record1);
            db.SaveChanges();

This fails on runtime with "A first chance exception of type 'Apache.Cassandra.InvalidRequestException' occurred in FluentCassandra.dll" exception in Casssandra.cs: public void recv_batch_mutate()

Took me some time to figure out what is wrong (even though it now seems obvious): key is of 0 bytes length.

There should be a better error message and/or exception from fluentcassandra on .CreateRecord() method maybe..

Querying With Composite Keys Doesn't Work

I have been playing with the FluentCassandra project and so far I find it really great to interact with Cassandra.

But this week end I stumbled on one massive issue, and I am pretty sure that it comes from my inability to use it properly.
So I thought that you might be able to help me with it.

Basically I have a ColumnFamily called "Data" which uses Composite Keys of type <AsciiType, AsciiType> for the Row Keys.
Inserting Data using the code below works fine:

        public void InsertMarketData(string keyspace, Data data)
        {
            using (var db = new CassandraContext(keyspace: keyspace, server: _server))
            {
                var productFamily = db.GetColumnFamily("Data");
                var key = new CompositeType<AsciiType, AsciiType>(data.Key1, data.Key2);

                var post = productFamily.CreateRecord(key);
                db.Attach(post);
                foreach (var fieldValue in data.Values)
                {
                    if (!post.TrySetColumn(fieldValue.Key, fieldValue.Value))
                        throw new InvalidDataException(string.Format("Can't add {0}:{1}", fieldValue.Key,
                                                                     fieldValue.Value));
                }
                db.SaveChanges();
            }
        }

Doing this I end up with a Row with a key being "TT:A" and one column [name:"Status" / value:"Working"] and I am able to retrieve it using cqlsh and cassandra-cli using this syntax for the composite key : "TT:A".

But to retrieve this piece of data from the C#, I use this method:

        public dynamic GetData(string keyspace, string key1, string key2, params CassandraObject[] columns)
        {
            CompositeType<AsciiType, AsciiType> key = new CompositeType<AsciiType, AsciiType>(key1, key2);
            using (var db = new CassandraContext(keyspace: keyspace, server: _server))
            {
                var productFamily = db.GetColumnFamily("Data");
                return productFamily.Get(key).FetchColumns(columns).FirstOrDefault().AsDynamic();
            }
        }

I have tried to modify this function and everything single time I get an 'Apache.Cassandra.InvalidRequestException' Exception.
There is obviously something I don't do properly ....

The following is being used for the table schema:

key_validation_class:
org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.AsciiType,org.apache.cassandra.db.marshal.AsciiType)

comparator_type:
org.apache.cassandra.db.marshal.AsciiType

default_validation_class:
org.apache.cassandra.db.marshal.BytesType

I understand if you don't have time or don't want to get into everybody's issues.
But if you had just a few moments to look at my case that would extremely helpful.

Best Regards,
Pierre Mulotte

Black Listing To Aggressive

In the RoundRobinServerManager, if a connection cannot be made to a server, it is added to the blacklist. Once it's in the blacklist, it is there for the life time of RoundRobinServerManager, which is a problem if a connection pool is used, and the CassandraContext is held open for a long time.

Check the ColumnName is existing

In 2010/06/14 update, the dynamic properties will return default cast value instead of throw a runtime exception. Basically, it is great approach and avoid throw exception.
But, In some scenario, it will cause confuse between default value and null value. Does any method to check ColumnName is existing or any suggestions ?

Thanks a lot,

  • ROBIN SU

What's the license?

Hi, I'm interested in this package, but need to know what the license is. Thank you!

load balancing, failover behaivor, connection pooling support as hector

Hi,

Great project, thanks for sharing ! Can you please add the features of hector http://github.com/rantav/hector
I know It's not a simple job and hectorsharp also tried this, but this project seems have more potential.

And I didn't look at the code but EmitMapper http://emitmapper.codeplex.com/ may help for ultra fast mapping and http://fasterflect.codeplex.com/ may help for fast reflection calls to increase performance...

Best Regards, SI

Bug at LongTypeConverter

LongTypeConverter.cs line 24.

when value is byte[], it should:

return BitConverter.ToInt64((byte[])value, 0);

instead of:

return BitConverter.GetBytes((long)value);

Problems with CassandraContext disposal

I have following method in my test application :

    public static bool SetupKeyspace(string keyspaceName, Server server)
        {
            try
            {
                using (var db = new CassandraContext(keyspaceName, server))
                {
                    var keyspaceExists = db.KeyspaceExists(keyspaceName); //exception here
                    if (keyspaceExists)
                    {
                        db.DropKeyspace(keyspaceName);
                    }
            }
            catch (CassandraException exception)
            {
                //MessageBox.Show(exception.Message, "Database error");
                return false;
            }
        }

When user somehow enters incorrect connection data, KeyspaceExists throws CassandraException, method returns false, and then in few seconds ArgumentNullException is thrown in Connection.cs at line 80 in public bool IsOpen :
lock (_transport) // The value can not be null
That happens during context disposal i guess. Fixed error by putting "if (_transport == null) return false;" check before lock, but don't know if that's correct. What is the simplest way to detect if CassandraContext is valid?

Server timeout is lost with default port

If "Server" part of connection string doesn't contain a port, Server.Timeout will always be set to 0 in ConnectionBuilder(connectionString). This creates a problem if multiple servers are specified, since the timeout must be non-zero in that case.

countercolumntype missing in CassandraType

Hi

countercolumntype is missing in Parse method in CassandraType.cs

case "countercolumntype": _type = typeof(CounterColumnType); break;

Regards,
Ásgeir Halldórsson

"cannot parse 'Key1' as hex bytes" error when doing a CQL INSERT

When I try to do a CQL INSERT statement using ExecuteNoQuery I get a "cannot parse 'Key1' as hex bytes" error. The same error is thrown when trying to do an UPDATE statement also. See example below.

        using (CassandraContext db = new CassandraContext("JeffSTest", new Server("10.15.10.70")))
        {
            db.ExecuteNonQuery("INSERT INTO TestCF (KEY, Column1) VALUES('Key1', 'Value1')");
        }

Make A Documentation

There is neither a documentation, nor intellisense-aware comments, nor are there any comments in the code. I am stuck at a point, which could be easily passed with only one or two sentences.
Or isn't this project made for public use?

FormatCql Helper Method

I've created a helper format string method that will make sure the arguments being passed into a CQL statement are appropriately escaped. I'm not sure where the best place to put this method would be but I think it would be handy to be part of this project. Mabye some sort of public Helper methods class.

    /// <summary>
    /// Escapse the provided string for use with CQL.
    /// </summary>
    /// <param name="value">The string value to escape.</param>
    /// <returns>The escaped value.</returns>
    public static string EscapeForCql(string value)
    {
        string returnValue = value;

        if(value != null)
        {
            returnValue = value.Replace("'", "''");
        }

        return returnValue;
    }

    /// <summary>
    /// Replaces the format item in a specified string with the string representation of a corresponding object in a specified array.
    /// Arguments are updated to make sure reserved characters are escaped to support Cassandra's CQL.
    /// </summary>
    /// <param name="format">A composite format string.</param>
    /// <param name="args">An object array that contains zero or more objects to format.</param>
    /// <returns>A copy of format in which the format items have been replaced by the string representation of the corresponding objects in args.
    /// Each arg has also been updated to escape reserved CQL characters.</returns>
    public static string FormatCql(string format, params object[] args)
    {
        object[] cleanArgs;

        if (args != null && args.Length > 0)
        {
            cleanArgs = new object[args.Length];
            for (int lp1 = 0; lp1 < args.Length; lp1++)
            {
                if (args[lp1] != null)
                {
                    //Espace single quote by replacing it with two single quotes.
                    cleanArgs[lp1] = EscapeForCql(args[lp1].ToString());
                }
                else
                {
                    cleanArgs[lp1] = args[lp1];
                }
            }
        }
        else
        {
            cleanArgs = args;
        }

        return string.Format(format, cleanArgs);
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.