Changes between Welle 1.5.0 and 2.0

Changes in K/V Function Return Values

Welle 2.0 changes how Riak responses are represented as Clojure maps.
Welle now will correctly preserve all vector clocks associated with multiple
siblings in the response and the response itself.

This means that welle.kv/modify will work correctly and won't make sibling
explosions worse.

The most important part of the change is how responses are represented:
every response is an immutable map that has :result key as well as other
metadata keys (:has-value?, :has-siblings?, :modified?, :content-type and so on).

This contrasts with earlier versions, where results were returned directly by functions
such as welle.kv/fetch, it is now possible to destructure the response in order to
obtain the returned value:

Clojure 1.6 By Default

The project now depends on org.clojure/clojure version 1.6.0. It is
still compatible with Clojure 1.4 and if your project.clj depends on
a different version, it will be used, but 1.6 is the default now.

We encourage all users to upgrade to 1.6, it is a drop-in replacement
for the majority of projects out there.

Validateur Dependency Dropped

Optional Keywordization of Keys With JSON Serialization

Automatic JSON serialization previously unconditionally converted keys to keywords.
This may be a problem for some projects, because keywords are not garbage collected.

clojurewerkz.welle.conversion/*convert-json-keys-to-keywords* is a new dynamic var that
controls this behavior. When bound to false, automatic JSON serialization won't convert
keys to keywords.

Changes between Welle 1.4.0 and 1.5.0

clojurewerkz.welle.kv/modify

clojurewerkz.welle.kv/modify is a new function that combines clojurewerkz.welle.kv/fetch and
clojurewerkz.welle.kv/store with a user-provided mutation functions. The mutation function
should take a single Riak object as an immutable map and return a modified one.

In case of siblings, a resolver should be used.

clojurewerkz.welle.kv/modify will update modification timestamp of the object.

clojurewerkz.welle.kv/modify takes the same options as clojurewerkz.welle.kv/fetch and
clojurewerkz.welle.kv/store

Conflcit Resolvers

clojurewerkz.welle.kv/fetch, and clojurewerkz.welle.kv/store now accept a new
option: :resolver. Resolvers are basically pure functions that take a collection of
siblings and return a collection of Riak object maps.

Resolvers can be created using
clojurewerkz.welle.conversion/resolver-from which takes a function that accepts a collection
of deserialized (unless fetch was told otherwise) values and applies any conflict resolution
logic necessary.

clojurewerkz.welle.kv/fetch-one now also supports resolvers via the :resolver option.
It will raise an exception if siblings are detected and no resolver is provided.

Retriers

clojurewerkz.welle.kv/fetch, clojurewerkz.welle.kv/fetch-one, clojurewerkz.welle.kv/store,
clojurewerkz.welle.kv/delete, and clojurewerkz.welle.kv/index-query now retry operations
that fail due to a network issue or any other exception.

By default, the operations will be retrier 3 times. It is possible to provide a custom
retrier using the :retrier option. Retriers can be created using
clojurewerkz.welle.conversion/retrier-from which takes a function that accepts a callable
(an operation that may need to be retried) and needs to invoke it, handling exceptions
and applying any retrying logic needed.

clojurewerkz.welle.conversion/counting-retrier produces a retrier that will retry an operation
given number of times. This is the kind of retrier Welle uses by default.

Skipping Deserialization for clojurewerkz.welle.kv/fetch

clojurewerkz.welle.kv/fetch supports a new boolean option :skip-deserialize that allows
automatic deserialization to be skipped.

Contributed by Jonas Tehler.

Clojure 1.5 By Default

Welle now depends on org.clojure/clojure version 1.5.1. It is
still compatible with Clojure 1.3+ and if your project.clj depends
on a different version, it will be used, but 1.5 is the default now.

We encourage all users to upgrade to 1.5, it is a drop-in replacement
for the majority of projects out there.

Changes between Welle 1.3.0 and 1.4.0

Tombstones Handling

In eventually consistent systems such as Riak, deleted objects may
sometimes "reappear" due to concurrent modifications. Welle by
default will filter out tombstones in
clojurewerkz.welle.kv/fetch. If you want to retrieve all objects
including tombstones, pass :return-deleted-vlock as true to
clojurewerkz.welle.kv/fetch. This behavior is new in Welle 1.4.0
which uses Riak Java client 1.1.0.

Documents stored via Riak K/V (clojurewerkz.welle.kv/store) with the content type of application/json, application/xml or text/plain will be indexed
if Riak Search is enabled for the bucket.

Support for SMILE

Welle now provides transparent serialization and deserialization support for SMILE, just like it has for
JSON, compressed data and Clojure reader. To use it, set :content-type of a value to "application/jackson-smile".

Cheshire For JSON Serliazation

Clojure 1.4 By Default

Welle now depends on org.clojure/clojure version 1.4.0. It is still compatible with Clojure 1.3 and if your project.clj depends
on 1.3, it will be used, but 1.4 is the default now.

We encourage all users to upgrade to 1.4, it is a drop-in replacement for the majority of projects out there.

kv/fetch-all

clojurewerkz.welle.kv/fetch-all is a convenience functions that retrieves multiple keys concurrently (and in parallel, on multi-core
machines), optimistically assuming there will be no siblings for each one.

Changes between Welle 1.1.0 and 1.2.0

Validateur 1.2.0

Buckets with enabled search now get indexing precommit hook added automatically. Previously if the precommit hook
was not added in addition, values stored in the bucket were not indexed.

Documentation correction for clojurewerkz.welle.buckets/update

clojurewerkz.welle.buckets/update doc string incorrectly listed the name of the option that enables search:
it is :enable-search, not :enabled-for-search.

Changes between Welle 1.0.0 and 1.1.0

Minor core.cache support improvement

clojurewerkz.welle.cache/basic-welle-cache-factory now has a 3-arity that accepts bucket name, content type and W to
use for cache writes.

Cluster client support

clojurewerkz.welle.core/connect-to-cluster and clojurewerkz.welle.core/connect-to-cluster! are new functions that
use just like clojurewerkz.welle.core/connect and clojurewerkz.welle.core/connect! but use cluster clients.

Cluster client is a regular client (with exactly the same API) that does round-robin balancing of requests between multiple hosts
in a cluster.

clojurewerkz.welle.core/connect-to-cluster-via-pb and clojurewerkz.welle.core/connect-to-cluster-via-pb! are the PBC
transport equivalents.

Bug fixes

core.cache implementation no longer fails to compile when building uberjars.

kv/delete-all-via-2i

clojurewerkz.welle.kv/delete-all-via-2i is a new convenience function that combines clojurewerkz.welle.kv/index-query
and clojurewerkz.welle.kv/delete-all: it concurrently deletes multiple keys retrieved via a 2i query:

Changes between Welle 1.0.0-alpha4 and 1.0.0-alpha5

clojurewerkz.welle.buckets/create is now clojurewerkz.welle.buckets/update

clojurewerkz.welle.buckets/update better reflects what the function really does. However, clojurewerkz.welle.buckets/create may
reflect the intent a bit better in certain cases so it is kept for backwards compatibility.

Changes between Welle 1.0.0-alpha3 and 1.0.0-alpha4

Map/Reduce support: clojurewerkz.welle.mr

Initial map/reduce queries support has been implemented, everything related to it
resides under the new clojurewerkz.welle.mr namespace.

clojure.core.cache implementation on top of Riak: clojurewerkz.welle.cache

clojurewerkz.welle.cache provides an implementation of clojure.core.cache cache store
protocol on top of Riak.

clojurewerkz.welle.kv/fetch-one

clojurewerkz.welle.kv/fetch-one is a convenience function for fetching objects in cases where conflicts/siblings are not expected.
For example, it is common to use "last write wins" strategy for caches and such. clojurewerkz.welle.kv/fetch-one works
the same way clojurewerkz.welle.kv/fetch does (and accepts exactly the same arguments) but always returns a single object,
not a list.

In case the response contains siblings, a IllegalStateException will be thrown.

Validateur 1.1.0

Client Id Support

clojurewerkz.welle.core/connect now has one more arity that lets client id to be specified. In addition,
if client id is not specified explicitly, it will be generated and set.

clojurewerkz.welle.objects is now clojurewerkz.welle.kv

clojurewerkz.welle.objects namespace was renamed to clojurewerkz.welle.kv

Changes between Welle 1.0.0-alpha2 and 1.0.0-alpha3

GZipped JSON Serialization Support

New application/json+gzip content type serializer allows Riak object values to be serialized as JSON and compressed
with gzip (using JDK's GZip implementation). Compatible with both HTTP and PB interfaces.

Changes between Welle 1.0.0-alpha1 and 1.0.0-alpha2

Clojure Serialization Support

If content type passed to clojurewerkz.welle.objects/store is application/clojure, Clojure reader will be used to serialize
and deserialize object value. On Clojure 1.4+, this means you can transparently store and fetch objects that include dates, too
(thanks to 1.4's extensible reader/instant literal support).

JSON Serialization Bug Fixes

Welle now works around this Java client bug that used to break
application/json; charset=UTF-8 serialization.

User Metadata Normalization

clojurewerkz.welle.objects/store now normalizes metadata by stringifying all keys and requiring that all values
are strings. This is due to the current (Riak 1.1) Java client limitations.

clojurewerkz.welle.objects/delete-all

clojurewerkz.welle.objects/delete-all is a convenient way to delete multiple keys. Since Riak (as of version 1.1) does
not provide a way to delete multiple objects in a single request, this function will use clojure.core/pmap to perform
multiple concurrent deletion requests. This implementation may or may not be suitable for your use case.

Switch to RawClient

Welle now uses RawClient API of the underlying Riak Java driver. This makes the API a lot more Clojuric and
much closer to Sumo. This also makes it more flexible, allowing us
to perform automatic serialization/deserialization for stored objects for a few most commonly used content
types and control conflicts resolution without heavy boilerplate Java interoperability code in end user
applications.