working java,python, js then added rust, then rewired java to j
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
# BStore-j
|
||||
|
||||
Explicit-first successor line for the Java BStore data access layer.
|
||||
|
||||
`bstore-j` starts as a clean copy of `bstore-java`, but evolves independently:
|
||||
|
||||
- build and publication identity are separate
|
||||
- the package surface remains familiar
|
||||
- explicit model definition becomes first-class
|
||||
- reflection remains available only as optional sugar
|
||||
- GraalVM-friendlier operation is a design goal
|
||||
|
||||
## What It Is
|
||||
|
||||
`bstore-j` has two main pieces:
|
||||
|
||||
- `com.reliancy.rec`
|
||||
- lightweight structured data types
|
||||
- JSON-like records, headers, slots, arrays/objects
|
||||
- `com.reliancy.dbo`
|
||||
- storage-oriented entity/field/record model
|
||||
- SQL-inspired actions and filters
|
||||
- SQL backend via `com.reliancy.dbo.sql`
|
||||
|
||||
The API is inspired by SQL, but the design goal is not to reproduce SQLAlchemy
|
||||
or raw SQL access. The goal is a small, consistent data layer that can later be
|
||||
ported across languages and backed by other systems.
|
||||
|
||||
## Current Direction
|
||||
|
||||
The Java codebase is the reference implementation for:
|
||||
|
||||
- CRUD over entities and fields
|
||||
- backend-neutral `dbo` contracts
|
||||
- SQL as the first reference backend
|
||||
- metadata/migration support through `dbo.meta`
|
||||
|
||||
The current meta model is intentionally lean:
|
||||
|
||||
- `ChangeEvent` is the canonical persisted history
|
||||
- `DataOriginator` is a module/plugin registry snapshot
|
||||
- `EntityDefinition` and `FieldDefinition` are utility/transient planning models
|
||||
|
||||
## Core Features
|
||||
|
||||
- explicit and reflective entity definition paths
|
||||
- CRUD with `Terminal`, `Action`, `Check`, and `Ordering`
|
||||
- joined inheritance support
|
||||
- SQL backends for PostgreSQL/MySQL/SQL Server/Oracle/H2
|
||||
- streaming loads and batched writes
|
||||
- migration/change discovery through `MetaTerminal`
|
||||
- replay-safe structural change application
|
||||
- startup-oriented migration flow
|
||||
|
||||
## Status
|
||||
|
||||
The library is being revised so that:
|
||||
|
||||
- explicit metadata becomes the canonical runtime path
|
||||
- `DBO` remains the runtime record type
|
||||
- typed non-`DBO` models can use adapters
|
||||
- reflection and annotation-driven publication remain optional convenience
|
||||
|
||||
The active implementation plan lives in:
|
||||
|
||||
- [`../docs/BSTORE_JAVA_BACKPORT_PLAN.md`](../docs/BSTORE_JAVA_BACKPORT_PLAN.md)
|
||||
|
||||
## Explicit-First Example
|
||||
|
||||
```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")));
|
||||
```
|
||||
|
||||
## Optional Sugar Example
|
||||
|
||||
```java
|
||||
import com.reliancy.dbo.DBO;
|
||||
import com.reliancy.dbo.Entity;
|
||||
import com.reliancy.dbo.Field;
|
||||
import com.reliancy.dbo.sugar.BStoreRegistry;
|
||||
import com.reliancy.dbo.sql.SQLTerminal;
|
||||
|
||||
@Entity.Info(name="public.person")
|
||||
public class Person extends DBO {
|
||||
public static final Field ID = Field.Int("id").setPk(true).setAutoIncrement(true);
|
||||
public static final Field NAME = Field.Str("name");
|
||||
}
|
||||
|
||||
SQLTerminal db = new SQLTerminal("postgres://user:pass@localhost:5432/appdb");
|
||||
BStoreRegistry registry = BStoreRegistry.builder().register(Person.class).build();
|
||||
|
||||
registry.publishAll();
|
||||
db.meta().migrate("core", "person-v1", registry.entity(Person.class));
|
||||
|
||||
Person loaded = db.load(registry.adapter(Person.class), 1);
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
```java
|
||||
import com.reliancy.dbo.DBO;
|
||||
import com.reliancy.dbo.Entity;
|
||||
import com.reliancy.dbo.Field;
|
||||
import com.reliancy.dbo.sql.SQLTerminal;
|
||||
|
||||
@Entity.Info(name="public.person")
|
||||
public class Person extends DBO {
|
||||
public static final Field ID = Field.Int("id").setPk(true).setAutoIncrement(true);
|
||||
public static final Field NAME = Field.Str("name").setTypeParams("255");
|
||||
public static final Field AGE = Field.Int("age");
|
||||
}
|
||||
|
||||
SQLTerminal db = new SQLTerminal("postgres://user:pass@localhost:5432/appdb");
|
||||
|
||||
Person person = new Person();
|
||||
person.set(Person.NAME, "Alice");
|
||||
person.set(Person.AGE, 30);
|
||||
db.save(person);
|
||||
|
||||
Person loaded = db.load(Person.class, person.get(Person.ID));
|
||||
```
|
||||
|
||||
## Query Example
|
||||
|
||||
```java
|
||||
import com.reliancy.dbo.Action;
|
||||
import com.reliancy.dbo.DBO;
|
||||
|
||||
try (Action action = db.begin()
|
||||
.load(Person.class)
|
||||
.filterBy(Person.AGE.gte(18))
|
||||
.orderBy(Person.NAME.asc())
|
||||
.limit(100)
|
||||
.execute()) {
|
||||
for (DBO row : action) {
|
||||
System.out.println(row.get(Person.NAME));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Startup Migration Example
|
||||
|
||||
```java
|
||||
import com.reliancy.dbo.Entity;
|
||||
import com.reliancy.dbo.meta.MetaTerminal;
|
||||
|
||||
MetaTerminal meta = db.meta(Entity.recall(Person.class));
|
||||
|
||||
meta.migrate(
|
||||
"core-module",
|
||||
"release-2026-03-17",
|
||||
Entity.recall(Person.class)
|
||||
);
|
||||
```
|
||||
|
||||
Current behavior:
|
||||
|
||||
- ensures the required `bstore.change_event` history table exists
|
||||
- discovers expected entity structure from code
|
||||
- discovers actual structure from the backend
|
||||
- computes ordered structural changes
|
||||
- applies unapplied changes
|
||||
- records applied changes in the change log
|
||||
|
||||
## Module Registry Example
|
||||
|
||||
```java
|
||||
import com.reliancy.dbo.meta.DataOriginator;
|
||||
|
||||
DataOriginator module = new DataOriginator();
|
||||
module.set(DataOriginator.ID, "core-module");
|
||||
module.set(DataOriginator.ORIGINATOR_ID, "core-module");
|
||||
module.set(DataOriginator.ORIGINATOR_VERSION, "1.0.0");
|
||||
module.set(DataOriginator.INSTALLED_VERSION, "1.0.0");
|
||||
module.set(DataOriginator.DESCRIPTION, "Core application module");
|
||||
|
||||
db.save(module);
|
||||
```
|
||||
|
||||
`DataOriginator` is meant for module/plugin registry data, not arbitrary module
|
||||
state and not detailed migration history.
|
||||
|
||||
## What Is Supported Today
|
||||
|
||||
- install-style schema creation
|
||||
- additive schema upgrades
|
||||
- safe table rename within the same schema
|
||||
- replay-safe change application
|
||||
- schema downgrade by replaying a contraction plan
|
||||
|
||||
## What Is Intentionally Not Broad Yet
|
||||
|
||||
- rich relationship/foreign-key navigation
|
||||
- generic rollback synthesis
|
||||
- plugin settings/state storage in meta records
|
||||
- non-SQL backends in Java
|
||||
|
||||
## Testing
|
||||
|
||||
The curated test suite uses a Postgres database via `DB_URL`.
|
||||
|
||||
```bash
|
||||
export DB_URL="postgres://user:pass@localhost:5432/testdb"
|
||||
./gradlew test
|
||||
```
|
||||
|
||||
There are focused integration tests for:
|
||||
|
||||
- CRUD and SQL backend behavior
|
||||
- change discovery ordering
|
||||
- change replay/idempotency
|
||||
- startup migration flow
|
||||
- install/upgrade/downgrade lifecycle at the schema level
|
||||
|
||||
## Docs
|
||||
|
||||
- [`../docs/BSTORE_DBO_CONTRACT.md`](../docs/BSTORE_DBO_CONTRACT.md)
|
||||
- [`../docs/BSTORE_META_CONTRACT.md`](../docs/BSTORE_META_CONTRACT.md)
|
||||
- [`../docs/BSTORE_JAVA_PLAN.md`](../docs/BSTORE_JAVA_PLAN.md)
|
||||
|
||||
## License
|
||||
|
||||
GNU Lesser General Public License, Version 3.0
|
||||
|
||||
Reference in New Issue
Block a user