npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

cassandra-jpa

v3.0.5

Published

Imergo Node.js Javascript Persistence API for Apache Cassandra.

Downloads

68

Readme

Javascript (Node.js) Persistence API (JPA) for Apache Cassandra

NPM Version Node

A persistence layer for using Apache Cassandra with Node.js based on the latest DataStax Cassandra Driver.

This module brings features from the Java World (JPA) and try to make life with Cassandra easier, mostly for people coming from the JAVA World.

The idea is to make the API as similar as possible to the latest JPA so that Java - and not only - developers to start easily with cassandra. Last but not least, this modules provides a good base for any Node.js developer for any kind of project that uses cassandra as its reposistory.

Installation

$ npm install cassandra-jpa

Prerequistics

  • ES6 (Node.js > 4.1.0)
  • CQL 3
  • Compatible with Cassandra / Cassandra driver 3

Design

  • Flexible configuration
  • Datastax Cassandra Driver Configuration
  • Configurable entity class, (TODO: allow for not having to extend - interface-like style)
  • OOP using classes
  • Self explainable Java (JPA) API based/inspired
  • NODE.js best practices

Features

  • Create, Drop Cassandra Tables programmatically
  • Create Indexes
  • Persist Javascript entities (JS Class extending Entity or Pure JS Objects)
  • Remove Javascript entities
  • Flexible configuration
  • Datastax Cassandra Driver Configuration
  • Configurable base entity class, (or use of Symbol as Interface still TODO)
  • Logging through the debug module (set the environment variable DEBUG to cassandra-jpa)
  • ES6 (Node.js > 4.0.0)
  • OOP using classes
  • Self explainable API
  • Following NODE.js best practices

Basic usage

Import the cassandra-persistence module

let jpa = require('cassandra-jpa');

Create your Entity Class Extending (optionally, see baseEntityClass in the configuration) the base Entity

Requirements

  • toJSON function should return entity property names same with table fields

See more in the foo example

Configure your persistence

configuration = new jpa.JPAConfiguration();
configuration.cassandra.contactPoints = ["localhost"];
configuration.cassandra.keyspace = "tests";

Make sure you defined the TTL - default in config or in every MetaModel. Set undefined if you do not need a TTL

You can use also ENV vars:

$ export CASSANDRA_DBHOST=host1,host2,host3 
$ export CASSANDRA_KEYSPACE=mykeyspace
$ export CASSANDRA_TTL=Number of seconds for default TTL

Implement your MetaModel class by extending the MetaModel

If you need to override the default toRow, fromRow function of the MetaModel, you need to extend the MetaModel class.

class FooMetaModel extends MetaModel {
  constructor(jpaConfig)
  {
    super(jpaConfig); 
    this.name = "foo";
    this.fields = new Map([["id", "timeuuid"], ["name", "text"], ["created", "timeuuid"],
        ["entity", "text"], ["entities", "list<text>"], ["simpleObjects", "list<text>"],
        ["enabled", "boolean"]]);
    this.partitionKeys = ["id"];
    this.clusteringColumns = new Map([["name", "ASC"]]);
    this.secondaryIndexes = ["name"];
    this.entityClass = Foo;
    this.ttl = undefined; //no ttl, or X secs, e.g. 86400 for one day
  }
}

See more in the foo example

Building criteriaQuery example

let emFactory = m.Persistence.createEntityManagerFactory("Foo", config);
let entityManager = emFactory.createEntityManager(fooMetaModel);
let cb = entityManager.getCriteriaBuilder();
let cq = cb.createQuery();
let op1 = cb.equal("id", TimeUuid.fromString(foo.id));
let op2 = cb.equal("name", foo.name);
let limit = 1;
let orderBy = "name";
let criteriaQuery = cq.where(cb.and([op1, op2]),limit, orderBy, true);

entityManager.findOne(function (error, res)
{
  assert(newFoo instanceof Foo);
  return callback(error, res);
}, criteriaQuery);

See more in the test

Override - extend object model adaptation methods in you MetaModel

This need to be done if the DefaultRowInterceptor does not cover your needs. Alternatively you could extend or replace the DefaultRowInterceptor and maybe also contribute the ideas here.

toRow(entity)
{
 // my specifics
 let row = super.toRow(entity);
  // my specifics
 return row;
}
fromRow(row)
{
 let entity = super.fromRow(row);
 // my specifics
 return entity;
}

See more in the test

When cassandra table should have extra properties comparing to the entity

In our metamodel class, initialize the extra params by giving the param names and an initial value (mostly null).

// add the extra field to the db schema
this.fields.set("newField", "text");
// allow for taking into account when querying
this.extraParams.set("newField", null);

See more in the action

Then when persisting we add the extra params like this:

fooMetaModel.extraParams.set("newField", "some value");

And when we select from db we get of course the entity (missing the extra params) but we can get the extra ones doing:

fooMetaModel.extraParams.get("newField")

See more in the action

API

EntityManger

| Function | Arguments |Returns |Description | | ------------- | ------------- |------------- |------------- | | persist | entity, callback, [metaModel] | callback(error, result) | Persist an entity | | persistAll | entities, callback, [metaModel] | callback(error, result) | Persist an arry of entities | | updateByCriteria | entity, callback, criteriaQuery, [metaModel] | callback(error, result) | Update Row based on criteriaQuery | | removeByCriteria | callback, criteriaQuery, [metaModel] | callback(error, result) | Update Row(s) based on criteriaQuery | | findOne | callback, criteriaQuery, [metaModel] | callback(error, result) | Find one entity based on criteriaQuery | | findAll | callback, criteriaQuery, [metaModel] | callback(error, result) | Find all entities based on criteriaQuery | | query | queryObject, callback | callback(error, result) | general cassandra driver query | | truncate | queryObjects, callback | callback(error, result) | Truncate a table based on MetaModel | | createTable | callback, [metaModel] | callback(error, result) | Create a table based on MetaModel | | insertIndexes | callback, [metaModel] | callback(error, result) | Create indexes based on MetaModel | | dropIndexes | callback, [metaModel] | callback(error, result) | Drop indexes based on MetaModel | | dropTable | callback, [metaModel] | callback(error, result) | Drop Table based on MetaModel | | getCriteriaBuilder | [metaModel] | CriteriaBuilder | get the CriteriaBuilder | | getCriteriaQuery | [metaModel] | CriteriaQuery | get the CriteriaQuery |

Note: When an EntityManger is initiated using metaModel argument, the [metaModel] can be ommited.

CriteriaBuilder

| Function | Arguments |Returns |Description | | ------------- | ------------- |------------- |------------- | | and | expressions:array | q:string | combine expressions with and AND | | equal | x:string, y:ALL | q:string | Tests whether two expressions are equal | gt | x:string, y:ALL | q:string | Tests whether the first numeric expression is greater than the second numeric expression | | ge | x:string, y:ALL | q:string | Tests whether the first numeric expression is greater than or equal to the second numeric expression | | lt | x:string, y:ALL | q:string | Tests whether the first numeric expression is less than the second numeric expression | | le | x:string, y:ALL | q:string | Tests whether the first numeric expression is less than or equal to the second numeric expression |

CriteriaQuery

| Function | Arguments |Returns |Description | | ------------- | ------------- |------------- |------------- | | from | q | q:string | | | where | q, [limit:Number] , [orderBy:String], [allowFiltering:boolean] | q:string | |

Extending

DefaultRowInterceptor

The DefaultRowInterceptor is the defaul and abstract way that jpa maps the entity field to cassandra rows depending on the field type defined in MetaModel. The following types are supported:

  • uuid mapped to require('cassandra-driver').types.TimeUuid
  • timeuuid mapped to require('cassandra-driver').types.TimeUuid
  • text mapped to JSON.stringnify string
  • varchar mapped to JSON.stringnify string
  • list mapped to array of JSON.stringnify
  • list mapped to array of require('cassandra-driver').types.TimeUuid

The ones not listed are kept as they are, i.e. native support like string, Map etc...

The DefaultRowInterceptor can be extended and overriden.

TODO Features

  • Count Results
  • Count time

Licence

See license file.