Add detailed documentation in README.md for setup and usage
This commit is contained in:
182
readme.md
Normal file
182
readme.md
Normal file
@@ -0,0 +1,182 @@
|
||||
# Simple Persistence for Kotlin
|
||||
|
||||
A lightweight, file-based persistence library for Kotlin applications that provides a simple way to store, retrieve, and query objects.
|
||||
|
||||
## Available on Maven Central
|
||||
|
||||
```kotlin
|
||||
// Gradle Kotlin DSL
|
||||
implementation("nl.astraeus:simple-persistence-kotlin:1.1.5")
|
||||
```
|
||||
|
||||
```groovy
|
||||
// Gradle Groovy DSL
|
||||
implementation 'nl.astraeus:simple-persistence-kotlin:1.1.5'
|
||||
```
|
||||
|
||||
```xml
|
||||
<!-- Maven -->
|
||||
<dependency>
|
||||
<groupId>nl.astraeus</groupId>
|
||||
<artifactId>simple-persistence-kotlin</artifactId>
|
||||
<version>1.1.5</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- Simple and intuitive API for persisting Kotlin objects
|
||||
- Transaction support with ACID properties
|
||||
- Optimistic locking to handle concurrent modifications
|
||||
- Flexible indexing for efficient querying
|
||||
- Object references and collections handling
|
||||
- Encryption support for sensitive data
|
||||
- Snapshot and transaction log capabilities
|
||||
- File-based storage with automatic cleanup
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Define your model
|
||||
|
||||
```kotlin
|
||||
class Person(
|
||||
override var id: Long = 0,
|
||||
override var version: Long = 0,
|
||||
val name: String,
|
||||
val age: Int,
|
||||
company: Company? = null
|
||||
) : Persistable, Cloneable {
|
||||
var company: Company? by nullableReference(company)
|
||||
|
||||
companion object {
|
||||
private const val serialVersionUID: Long = 1L
|
||||
}
|
||||
}
|
||||
|
||||
class Company(
|
||||
override var id: Long = 0,
|
||||
override var version: Long = 0,
|
||||
val name: String
|
||||
) : Persistable, Cloneable {
|
||||
val persons: MutableCollection<Person> = referenceCollection()
|
||||
|
||||
companion object {
|
||||
private const val serialVersionUID: Long = 1L
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Initialize the persistence manager
|
||||
|
||||
```kotlin
|
||||
val persistent = Persistent(
|
||||
directory = File("data", "my-app"),
|
||||
indexes = arrayOf(
|
||||
index<Person>("name") { p -> (p as? Person)?.name ?: "" },
|
||||
index<Person>("age") { p -> (p as? Person)?.age ?: -1 },
|
||||
index<Company>("name") { p -> (p as? Company)?.name ?: "" }
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Perform CRUD operations
|
||||
|
||||
```kotlin
|
||||
// Create or update
|
||||
persistent.transaction {
|
||||
val person = Person(
|
||||
id = 1L,
|
||||
name = "John Doe",
|
||||
age = 30
|
||||
)
|
||||
|
||||
val company = Company(
|
||||
id = 1L,
|
||||
name = "ACME Inc."
|
||||
)
|
||||
|
||||
person.company = company
|
||||
company.persons.add(person)
|
||||
|
||||
store(person)
|
||||
store(company)
|
||||
}
|
||||
|
||||
// Read
|
||||
persistent.query {
|
||||
val person = find<Person>(1L)
|
||||
println("Found person: $person")
|
||||
|
||||
// Query by index
|
||||
val persons: List<Person> = findByIndex("age", 30)
|
||||
|
||||
// Search with predicate
|
||||
val results = search(Person::class) { p -> p.name.startsWith("John") }
|
||||
}
|
||||
|
||||
// Delete
|
||||
persistent.transaction {
|
||||
val person = find<Person>(1L)
|
||||
if (person != null) {
|
||||
delete(person)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
||||
- In-memory model: Your objects live in memory during normal operation for fast reads and writes.
|
||||
- Durable writes: Every create/update/delete inside a transaction is appended to on-disk transaction log files (*.trn). This is a write-ahead log approach.
|
||||
- Startup recovery: On application startup, the library replays the transaction logs (and any snapshot, if present) to rebuild the in-memory model.
|
||||
- Snapshots: You can create a compact on-disk snapshot (*.snp) of the current in-memory state. On the next startup, the snapshot is loaded first and only the newer transaction log files are replayed. This keeps startup time low without losing durability.
|
||||
|
||||
Tip: Call snapshot() periodically (or on controlled shutdown) and use removeOldFiles() to prune obsolete logs after a successful snapshot.
|
||||
|
||||
## Advanced Features
|
||||
|
||||
### Indexing
|
||||
|
||||
```kotlin
|
||||
// Define complex indexes
|
||||
val persistent = Persistent(
|
||||
directory = File("data", "my-app"),
|
||||
indexes = arrayOf(
|
||||
index<Person>("ageOver30") { p -> ((p as? Person)?.age ?: 0) > 30 }
|
||||
)
|
||||
)
|
||||
|
||||
// Query using indexes
|
||||
persistent.query {
|
||||
findByIndex<Person>("ageOver30", true).forEach { person ->
|
||||
println("Person over 30: ${person.name}")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Transactions
|
||||
|
||||
```kotlin
|
||||
// Read-only query
|
||||
persistent.query {
|
||||
// Only read operations allowed
|
||||
}
|
||||
|
||||
// Read-write transaction
|
||||
persistent.transaction {
|
||||
// Both read and write operations allowed
|
||||
}
|
||||
```
|
||||
|
||||
### Snapshots and Maintenance
|
||||
|
||||
```kotlin
|
||||
// Create a snapshot of the current state
|
||||
persistent.snapshot()
|
||||
|
||||
// Remove old transaction log files
|
||||
persistent.removeOldFiles()
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||
Reference in New Issue
Block a user