206 lines
4.9 KiB
Markdown
206 lines
4.9 KiB
Markdown
# bstore-j
|
|
|
|
`bstore-j` is a small Java data-access library built around entities, fields,
|
|
records, and schema change logs.
|
|
|
|
It is designed for applications that want a compact storage layer without
|
|
committing to a large ORM. The API stays close to database work, but it models
|
|
that work in Java types such as `Entity`, `Field`, `DBO`, `Action`, and
|
|
`Terminal` rather than centering everything on handwritten SQL strings.
|
|
|
|
## What It Provides
|
|
|
|
The library is organized around a few core areas:
|
|
|
|
- `com.reliancy.rec`
|
|
- lightweight structured record and value types
|
|
- `com.reliancy.dbo`
|
|
- entity and field definitions
|
|
- runtime record objects
|
|
- CRUD operations and query composition
|
|
- `com.reliancy.dbo.sql`
|
|
- SQL-backed terminal implementations
|
|
- `com.reliancy.dbo.meta`
|
|
- schema discovery
|
|
- ordered structural changes
|
|
- change log tracking for startup migrations
|
|
|
|
In practice, that gives you:
|
|
|
|
- explicit entity and field definitions
|
|
- a backend-neutral CRUD surface
|
|
- filtering, ordering, paging, and action execution
|
|
- SQL database support for the current Java implementation
|
|
- startup-oriented schema migration support
|
|
- a change history model built around append-only events
|
|
|
|
## Design Goals
|
|
|
|
`bstore-j` aims to be:
|
|
|
|
- small enough to understand without a large framework investment
|
|
- explicit about structure and schema
|
|
- usable as a runtime data layer in ordinary Java applications
|
|
- suitable for code-first schema installation and upgrade flows
|
|
|
|
It does not try to be a full ORM, rich object graph mapper, or a replacement
|
|
for every direct SQL use case.
|
|
|
|
## Installation
|
|
|
|
The published artifact is:
|
|
|
|
```text
|
|
com.reliancy:bstore-j:1.0.0-SNAPSHOT
|
|
```
|
|
|
|
If you have access to the Reliancy Maven repository:
|
|
|
|
```gradle
|
|
repositories {
|
|
mavenCentral()
|
|
maven {
|
|
url "https://repo.reliancy.com/repository/maven-snapshots"
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
implementation "com.reliancy:bstore-j:1.0.0-SNAPSHOT"
|
|
}
|
|
```
|
|
|
|
If you do not use that repository, you can build from source:
|
|
|
|
```bash
|
|
./gradlew jar
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
This example defines an entity, migrates the schema, writes a record, and loads
|
|
it back.
|
|
|
|
```java
|
|
import com.reliancy.dbo.DBO;
|
|
import com.reliancy.dbo.Entity;
|
|
import com.reliancy.dbo.Field;
|
|
import com.reliancy.dbo.sql.SQLTerminal;
|
|
|
|
Entity person = Entity.define("public.person")
|
|
.setId("person")
|
|
.field(
|
|
Field.Int("id").setPk(true).setAutoIncrement(true).nullable(false),
|
|
Field.Str("name").nullable(false),
|
|
Field.Int("age")
|
|
)
|
|
.publish();
|
|
|
|
SQLTerminal db = new SQLTerminal("postgres://user:pass@localhost:5432/appdb");
|
|
db.meta().migrate("core", "person-v1", person);
|
|
|
|
DBO alice = DBO.of(person);
|
|
alice.set(person.getField("name"), "Alice");
|
|
alice.set(person.getField("age"), 30);
|
|
db.save(alice);
|
|
|
|
DBO loaded = db.load(person, alice.get(person.getField("id")));
|
|
```
|
|
|
|
## Query Example
|
|
|
|
```java
|
|
import com.reliancy.dbo.Action;
|
|
import com.reliancy.dbo.DBO;
|
|
|
|
try (Action action = db.begin()
|
|
.load(person)
|
|
.filterBy(person.getField("age").gte(18))
|
|
.orderBy(person.getField("name").asc())
|
|
.limit(100)
|
|
.execute()) {
|
|
for (DBO row : action) {
|
|
System.out.println(row.get(person.getField("name")));
|
|
}
|
|
}
|
|
```
|
|
|
|
## Schema Migration Model
|
|
|
|
`bstore-j` includes a lean metadata layer intended for application startup
|
|
migrations.
|
|
|
|
The migration flow:
|
|
|
|
- discovers the expected entity structure from code
|
|
- discovers the current backend structure
|
|
- computes ordered structural changes
|
|
- applies unapplied changes
|
|
- records applied changes in a change-event log
|
|
|
|
The central types in this area are:
|
|
|
|
- `ChangeEvent`
|
|
- `DataOriginator`
|
|
- `EntityDefinition`
|
|
- `FieldDefinition`
|
|
|
|
## Databases
|
|
|
|
The Java implementation is SQL-oriented today. The project includes JDBC drivers for:
|
|
|
|
- PostgreSQL
|
|
- H2
|
|
- Microsoft SQL Server (`mssql-jdbc`), used by Farnam Control 4.0 and similar apps.
|
|
|
|
Path-style URLs use `SQLTerminal`, for example:
|
|
|
|
```text
|
|
sqlserver://user:password@host:1433/databaseName
|
|
```
|
|
|
|
Optional semicolon properties after the database segment are forwarded into the JDBC URL (for example `encrypt=true`).
|
|
|
|
### Integration tests against SQL Server
|
|
|
|
Tests that need a live database read **`FC4_SQL_URL` first**, then **`DB_URL`** (historic convention). Example:
|
|
|
|
```bash
|
|
export FC4_SQL_URL='sqlserver://user:pass@host:1433/mydb'
|
|
./gradlew test --tests com.reliancy.dbo.sql.SQLTerminalSqlServerSmokeTest
|
|
```
|
|
|
|
The broader API is designed so application code can stay closer to entities and
|
|
actions than to vendor-specific SQL strings.
|
|
|
|
## Build And Test
|
|
|
|
Build the library:
|
|
|
|
```bash
|
|
./gradlew build
|
|
```
|
|
|
|
Run the test suite:
|
|
|
|
```bash
|
|
export DB_URL="postgres://user:pass@localhost:5432/testdb"
|
|
./gradlew test
|
|
```
|
|
|
|
The tests exercise CRUD behavior, SQL execution paths, schema change discovery,
|
|
and migration flows.
|
|
|
|
## Repository Layout
|
|
|
|
```text
|
|
bstore-j/
|
|
├── src/
|
|
├── build.gradle
|
|
├── extra.gradle
|
|
└── README.md
|
|
```
|
|
|
|
## License
|
|
|
|
GNU Lesser General Public License, Version 3.0
|