Java 8 and Scala Cassandra client.
Find a file
2017-08-18 16:48:01 -04:00
.idea Helenus was the son of King Priam and Queen Hecuba of Troy, and the twin brother of the prophetess Cassandra. Like Cassandra, he was always right, but unlike her, others believed him. Seems like a good name for a layer to access DataStax, Apache, or ScyllaDB's implementations of the Cassandra database. 2017-07-27 15:02:17 -04:00
lib Move Guava backwards to the last verison suppored by JDK 1.7 (ver 20.0). 2017-07-31 10:22:01 -04:00
src WIP: Where I stopped when building first a ResultSet cacne then layering an Entity cache. Lot's of tricky bits that were not falling into place. 2017-08-18 16:48:01 -04:00
.gitignore Enable partial updates using partial entity maps. 2017-08-01 12:48:14 -04:00
AUTHORS Helenus was the son of King Priam and Queen Hecuba of Troy, and the twin brother of the prophetess Cassandra. Like Cassandra, he was always right, but unlike her, others believed him. Seems like a good name for a layer to access DataStax, Apache, or ScyllaDB's implementations of the Cassandra database. 2017-07-27 15:02:17 -04:00
deploy.sh 1.2.0_2.11-SNAPSHOT 2015-06-16 15:50:14 -07:00
eclipse-formatting.xml eclipse-formatting 2015-03-16 17:03:17 -07:00
helenus-core.iml Start plumbing for Dropwizard metrics and Zipkin tracing. Ensure proper bean value when working with enums. 2017-08-08 12:02:32 -04:00
LICENSE Initial commit 2015-02-26 12:42:59 -08:00
NOTES WIP: still working toward a solid caching scheme, progress but far from done. 2017-08-18 16:44:30 -04:00
pom.xml Update version to 2.0.21 2017-08-17 12:15:48 -04:00
README.md Remove Scala support and trim Future support at some point I'll re-introduce using Java 8 classes rather than Guava's or Scala's 2017-08-04 11:18:54 -04:00
sign.sh 1.2.0_2.11-SNAPSHOT 2015-06-16 15:50:14 -07:00

Helenus

Fast and easy, functional style cutting edge Java 8 Cassandra client for C* 3.x

Features

  • Leverages Java 8 language capabilities to build CQL queries
  • Simple function-style stream API
  • Reactive asynchronous and synchronous API
  • Provides Java mapping for Tables, Tuples, UDTs (User Defined Type), Collections, UDT Collections, Tuple Collections
  • Uses lazy mapping in all cases where possible
  • Supports Java 8 Futures and Guava ListenableFuture

Requirements

  • JVM 8
  • Datastax Driver 3.x
  • Cassandra 3.x
  • Maven

Maven

Latest release dependency:

<dependencies>
	<dependency>
		<groupId>net.helenus</groupId>
		<artifactId>helenus-core</artifactId>
		<version>1.1.0_2.11</version>
	</dependency>
</dependencies>

Simple Example

Model definition:

@Table
public interface Timeline {

	@PartitionKey
	UUID userId();

	@ClusteringColumn
	@Types.Timeuuid
	Date timestamp();

	@Column
	String text();

}

Session initialization:

HelenusSession session = Helenus.init(getSession()).showCql().add(Timeline.class).autoCreateDrop().get();
Timeline timeline = Helenus.dsl(Timeline.class, session.getMetadata());

Select example:

session.select(timeline::userId, timeline::timestamp, timeline::text)
  .where(timeline::userId, eq(userId))
  .orderBy(Query.desc(timeline::timestamp)).limit(5).sync()
  .forEach(System.out::println);

Insert example:

TimelineImpl post = new TimelineImpl();
post.userId=userId;
post.timestamp=new Date(postTime+1000L*i);
post.text="hello";
session.upsert(post).sync();

Model and Repository Example

Account model:

@Table
public interface Account {
	@PartitionKey
	String accountId();
	Date createdAt();
	String organization();
	String team();
	String timezone();
	Map<String, AccountUser> users();
}

AccountUser model:

@UDT
public interface AccountUser {
	String email();
	String firstName();
	String lastName();
}

Abstract repository:

public interface AbstractRepository {
	HelenusSession session();
}

Account repository:


public interface AccountRepository extends AbstractRepository {

	static final Account account = Helenus.dsl(Account.class);
	static final String DEFAULT_TIMEZONE = "America/Los_Angeles";
	default Future<Optional<Account>> findAccount(String accountId) {

		return session()
				.select(Account.class)
				.where(account::accountId, eq(accountId))
				.single()
				.future();
	}

	default Future<Fun.Tuple2<ResultSet, String>> createAccount(
			String email,
			AccountUser user,
			String organization,
			String team,
			String timezone) {

		String accountId = AccountId.next();

		if (timezone == null || timezone.isEmpty()) {
			timezone = DEFAULT_TIMEZONE;
		}

		return session()
			.insert()
			.value(account::accountId, accountId)
			.value(account::createdAt, new Date())
			.value(account::organization, organization)
			.value(account::team, team)
			.value(account::timezone, timezone)
			.value(account::users, ImmutableMap.of(email, user))
			.future(accountId);

	}

	default Future<ResultSet> putAccountUser(String accountId, String email, AccountUser user) {

		return session()
				.update()
				.put(account::users, email.toLowerCase(), user)
				.where(account::accountId, eq(accountId))
				.future();

	}

	default Future<ResultSet> removeAccountUser(String accountId, String email) {

		return session()
				.update()
				.put(account::users, email.toLowerCase(), null)
				.where(account::accountId, eq(accountId))
				.future();

	}

	default Future<ResultSet> dropAccount(String accountId) {

		return session()
				.delete()
				.where(account::accountId, eq(accountId))
				.future();

	}

}