Skip to content

Commit

Permalink
Merge pull request #21 from livetheoogway/issue-19
Browse files Browse the repository at this point in the history
Clean up of the references implementation
  • Loading branch information
Tushar-Naik authored Sep 9, 2023
2 parents d2c1914 + f0d88d0 commit 0eca0e3
Show file tree
Hide file tree
Showing 19 changed files with 501 additions and 199 deletions.
53 changes: 48 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,14 @@

## What is it?

This is supposed to be a very simple codebase, with even simpler features.<br>
I used to write these crud stores several times across use-cases, decided to create a simple interface, and some default
abstractions of some popular databases that implements the interface.<br>
I've been able to add the abstraction for aerospike. Impls for other databases are welcome.
abstractions of popular databases that implements the interface.<br>
I've been able to add the abstraction for aerospike. Impls for other databases as contributions are welcome.

## Features

#### The interface
The following functions are supported in the interface
The following are the CRUD ops in the Store interface (pretty self-explanatory)
```java
void create(final T item);
void update(final T item);
Expand All @@ -46,6 +45,11 @@ The following functions are supported in the interface
Map<String, T> get(final List<String> ids);
List<T> list();
```
An extension to this has been added (since 1.2.5) ReferenceExtendedStore, to support fetch by references through indexes if a Store is able to support it.
```java
void create(final T item, final List<String> refIds);
List<T> getByRefId(final String refId);
```

#### Cached Store

Expand All @@ -64,7 +68,12 @@ Store<MyData> store=new CachingStore(
#### Aerospike Store

This impl provides crud for your data by storing it in a default set (`data`), hides details of
serialization/de-serserialization, provides hook for proper error handling
serialization/de-serserialization, provides hook for proper error handling.<br>

It also supports indexing on references, as it implements a ReferenceExtendedStore.
So if you have data that needs to be retrieved through some reference ids, you can do so in an optimal manner. Internally,
a LIST s-index is created, and an Aerospike query on the index is fired during retrieval

Usage:

```java
Expand All @@ -84,6 +93,40 @@ public class MyAerospikeStore extends AerospikeStore<TestData> {
}
}
```
Your TestData class can look something like this
```java
@Builder
public record TestData(
String id,
String name,
int age) implements Id {
}
```

That is it, you should be good to go to do the following
```java
public class Logic {
private AerospikeStore<TestData> store
= new MyAerospikeStore(
AerospikeClientHelpers.aerospikeClient(AerospikeConfiguration.builder()
.hosts("...") // set the rest
.build()), new NamespaceSet("test", "test-set"),
mapper,
TestData.class,
new DefaultErrorHandler<>());

void myOperations() {
store.create(new TestData("Id001", "Rick", 47));
store.create(new TestData("Id001", "Rick", 47), List.of("animated"));
store.update(new TestData("Id001", "Rick Sanchez", 48));
Optional<TestData> result = store.get("Id001");
List<TestData> result = store.getByRefId("animated");
List<TestData> result = store.get(List.of("Id001", "Id002"));
List<TestData> result = store.list();
store.delete("Id001");
}
}
```

## How to use it

Expand Down
2 changes: 1 addition & 1 deletion aerospike-crud-store/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>crud-store</artifactId>
<groupId>com.livetheoogway.crudstore</groupId>
<version>1.2.4</version>
<version>1.2.5</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.livetheoogway.crudstore.core.Id;
import com.livetheoogway.crudstore.core.Store;
import com.livetheoogway.crudstore.core.ReferenceExtendedStore;
import lombok.extern.slf4j.Slf4j;

import javax.validation.constraints.NotEmpty;
Expand All @@ -47,7 +47,7 @@
import java.util.stream.IntStream;

@Slf4j
public abstract class AerospikeStore<T extends Id> implements Store<T> {
public abstract class AerospikeStore<T extends Id> implements ReferenceExtendedStore<T> {

private static final String DEFAULT_DATA_BIN = "data";
private static final String DEFAULT_REF_ID_BIN = "refId";
Expand Down Expand Up @@ -140,7 +140,12 @@ protected int expiration(T item) {
*/
@Override
public void create(final T item) {
write(item, createPolicy);
write(item, null, createPolicy);
}

@Override
public void create(final T item, List<String> refIds) {
write(item, refIds, createPolicy);
}

/**
Expand All @@ -150,7 +155,7 @@ public void create(final T item) {
*/
@Override
public void update(final T item) {
write(item, updateOnly);
write(item, null, updateOnly);
}


Expand Down Expand Up @@ -278,11 +283,10 @@ public Optional<T> extractItemForBulkOperations(String id, Record asRecord) {
}
}

protected RecordDetails recordDetails(T item) throws JsonProcessingException {
protected RecordDetails recordDetails(T item, List<String> refIds) throws JsonProcessingException {
final var dataBin = new Bin(storeSetting.dataBin(), mapper.writeValueAsString(item));
final var refIds = item.refIds();
if (refIds.isPresent()) {
final var refIdBin = new Bin(storeSetting.refIdBin(), refIds.get());
if (refIds!=null && !refIds.isEmpty()) {
final var refIdBin = new Bin(storeSetting.refIdBin(), refIds);
return new RecordDetails(expiration(item), dataBin, refIdBin);
}
return new RecordDetails(expiration(item), dataBin);
Expand Down Expand Up @@ -313,10 +317,10 @@ protected <R> R exec(final String operation, final String id, ESupplier<R> respo
}
}

private void write(final T item, WritePolicy defaultWritePolicy) {
private void write(final T item, List<String> refIds, WritePolicy defaultWritePolicy) {
final var id = item.id();
exec("operation:" + defaultWritePolicy.recordExistsAction, id, () -> {
final var recordDetails = recordDetails(item);
final var recordDetails = recordDetails(item, refIds);
var writePolicy = defaultWritePolicy;
if (recordDetails.expiration() > 0) {
writePolicy = new WritePolicy(writePolicy);
Expand Down
Loading

0 comments on commit 0eca0e3

Please sign in to comment.