helenus/README.md

222 lines
4.3 KiB
Markdown
Raw Normal View History

2015-06-05 21:18:50 +00:00
# casser
2015-06-05 21:22:57 +00:00
Fast and easy, functional style cutting edge Java 8 and Scala 2.11 Cassandra client
2015-03-12 08:08:42 +00:00
2015-06-05 21:22:57 +00:00
Current status: First application in production (may be more)
2015-03-26 06:00:46 +00:00
2015-03-18 03:17:44 +00:00
### Features
* Leverages Java 8 language capabilities to build CQL queries
2015-03-28 03:25:59 +00:00
* Simple function-style stream API
* Reactive asynchronous and synchronous API
2015-06-05 21:21:22 +00:00
* Provides Java mapping for Tables, Tuples, UDTs (User Defined Type), Collections, UDT Collections, Tuple Collections
2015-06-05 21:25:26 +00:00
* Uses lazy mapping in all cases where possible
* Supports Guava ListenableFuture and Scala Future
2015-03-18 03:17:44 +00:00
2015-03-12 08:08:42 +00:00
### Requirements
2015-06-05 21:18:50 +00:00
* Latest JVM 8
2015-03-28 03:25:59 +00:00
* Latest Datastax Driver 2.1.5
2015-04-28 03:52:55 +00:00
* Latest Cassandra 2.1.4
2015-06-05 21:18:50 +00:00
* Latest Scala 2.11
* Latest Maven as well
2015-03-12 08:08:42 +00:00
2015-03-30 19:49:44 +00:00
### Maven
2015-04-28 03:52:55 +00:00
Latest release dependency:
```
<dependencies>
<dependency>
<groupId>com.noorq.casser</groupId>
<artifactId>casser-core</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
```
2015-06-05 21:26:44 +00:00
Active development dependency for Scala 2.11:
2015-03-30 19:49:44 +00:00
```
2015-03-30 19:52:45 +00:00
<dependencies>
<dependency>
<groupId>com.noorq.casser</groupId>
<artifactId>casser-core</artifactId>
2015-06-05 21:26:44 +00:00
<version>1.1.0_2.11-SNAPSHOT</version>
2015-03-30 19:52:45 +00:00
</dependency>
</dependencies>
<repositories>
<repository>
<id>oss-sonatype</id>
<name>oss-sonatype</name>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
2015-03-30 19:49:44 +00:00
```
2015-06-05 21:33:02 +00:00
### Simple Example
2015-03-24 04:38:53 +00:00
2015-06-05 21:33:02 +00:00
Model definition:
2015-03-24 04:38:53 +00:00
```
2015-03-24 04:42:56 +00:00
@Table("timelines")
public interface Timeline {
@PartitionKey
2015-03-27 20:12:36 +00:00
UUID userId();
2015-06-05 21:18:50 +00:00
2015-03-24 04:42:56 +00:00
@ClusteringColumn
2015-04-16 23:54:30 +00:00
@Types.Timeuuid
2015-03-27 20:12:36 +00:00
Date timestamp();
2015-06-05 21:18:50 +00:00
2015-03-24 04:42:56 +00:00
@Column
2015-03-27 20:12:36 +00:00
String text();
2015-06-05 21:18:50 +00:00
2015-03-24 04:42:56 +00:00
}
```
Session initialization:
```
Timeline timeline = Casser.dsl(Timeline.class);
2015-03-25 04:58:58 +00:00
CasserSession session = Casser.init(getSession()).showCql().add(Timeline.class).autoCreateDrop().get();
2015-03-24 04:42:56 +00:00
```
2015-06-05 21:31:23 +00:00
Select example:
2015-03-24 04:42:56 +00:00
```
2015-03-27 20:12:36 +00:00
session.select(timeline::userId, timeline::timestamp, timeline::text)
2015-04-09 21:28:54 +00:00
.where(timeline::userId, Query.eq(userId))
.orderBy(Query.desc(timeline::timestamp)).limit(5).sync()
2015-03-24 04:42:56 +00:00
.forEach(System.out::println);
```
2015-06-05 21:31:23 +00:00
Insert example:
2015-03-24 04:42:56 +00:00
```
2015-03-27 20:12:36 +00:00
TimelineImpl post = new TimelineImpl();
post.userId=userId;
post.timestamp=new Date(postTime+1000L*i);
post.text="hello";
2015-03-24 04:42:56 +00:00
session.upsert(post).sync();
2015-03-24 04:38:53 +00:00
```
2015-06-05 21:31:23 +00:00
### 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();
}
```
2015-06-05 21:33:02 +00:00
AccountUser model:
```
@UDT
public interface AccountUser {
String email();
String firstName();
String lastName();
}
```
2015-06-05 21:31:23 +00:00
Abstract repository:
```
public interface AbstractRepository {
CasserSession session();
}
```
Account repository:
```
import scala.concurrent.Future;
public interface AccountRepository extends AbstractRepository {
static final Account account = Casser.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();
}
}
```