Compare commits
2 Commits
c0d9de9120
...
793b3b52fa
| Author | SHA1 | Date | |
|---|---|---|---|
| 793b3b52fa | |||
| ac64321225 |
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Rien Nentjes
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
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