From 57dba6a48cbf6c1dc1d96012e1688079f0dc1269 Mon Sep 17 00:00:00 2001 From: Amer Agovic Date: Fri, 1 May 2026 14:27:07 -0500 Subject: [PATCH] Add bstore-j public sync helper and refresh public README --- README.md | 264 +++++++++++++++++++++--------------------------------- 1 file changed, 103 insertions(+), 161 deletions(-) diff --git a/README.md b/README.md index ea6133d..4ce3a2a 100644 --- a/README.md +++ b/README.md @@ -1,71 +1,84 @@ -# BStore-j +# bstore-j -Explicit-first successor line for the Java BStore data access layer. +`bstore-j` is a small Java data-access library built around entities, fields, +records, and schema change logs. -`bstore-j` starts as a clean copy of `bstore-java`, but evolves independently: +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. -- 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 Provides -## What It Is - -`bstore-j` has two main pieces: +The library is organized around a few core areas: - `com.reliancy.rec` - - lightweight structured data types - - JSON-like records, headers, slots, arrays/objects + - lightweight structured record and value types - `com.reliancy.dbo` - - storage-oriented entity/field/record model - - SQL-inspired actions and filters - - SQL backend via `com.reliancy.dbo.sql` + - 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 -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. +In practice, that gives you: -## Current Direction +- 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 -The Java codebase is the reference implementation for: +## Design Goals -- CRUD over entities and fields -- backend-neutral `dbo` contracts -- SQL as the first reference backend -- metadata/migration support through `dbo.meta` +`bstore-j` aims to be: -The current meta model is intentionally lean: +- 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 -- `ChangeEvent` is the canonical persisted history -- `DataOriginator` is a module/plugin registry snapshot -- `EntityDefinition` and `FieldDefinition` are utility/transient planning models +It does not try to be a full ORM, rich object graph mapper, or a replacement +for every direct SQL use case. -## Core Features +## Installation -- 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 +The published artifact is: -## Status +```text +com.reliancy:bstore-j:1.0.0-SNAPSHOT +``` -The library is being revised so that: +If you have access to the Reliancy Maven repository: -- 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 +```gradle +repositories { + mavenCentral() + maven { + url "https://repo.reliancy.com/repository/maven-snapshots" + } +} -The active implementation plan lives in: +dependencies { + implementation "com.reliancy:bstore-j:1.0.0-SNAPSHOT" +} +``` -- [`../docs/BSTORE_JAVA_BACKPORT_PLAN.md`](../docs/BSTORE_JAVA_BACKPORT_PLAN.md) +If you do not use that repository, you can build from source: -## Explicit-First Example +```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; @@ -93,55 +106,6 @@ 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 @@ -149,98 +113,76 @@ 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()) + .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.NAME)); + System.out.println(row.get(person.getField("name"))); } } ``` -## Startup Migration Example +## Schema Migration Model -```java -import com.reliancy.dbo.Entity; -import com.reliancy.dbo.meta.MetaTerminal; +`bstore-j` includes a lean metadata layer intended for application startup +migrations. -MetaTerminal meta = db.meta(Entity.recall(Person.class)); +The migration flow: -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 +- discovers the expected entity structure from code +- discovers the current backend structure - computes ordered structural changes - applies unapplied changes -- records applied changes in the change log +- records applied changes in a change-event log -## Module Registry Example +The central types in this area are: -```java -import com.reliancy.dbo.meta.DataOriginator; +- `ChangeEvent` +- `DataOriginator` +- `EntityDefinition` +- `FieldDefinition` -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"); +## Databases -db.save(module); +The Java implementation is SQL-oriented today. The project currently includes +dependencies and test coverage around: + +- PostgreSQL +- H2 + +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 ``` -`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`. +Run the test suite: ```bash export DB_URL="postgres://user:pass@localhost:5432/testdb" ./gradlew test ``` -There are focused integration tests for: +The tests exercise CRUD behavior, SQL execution paths, schema change discovery, +and migration flows. -- CRUD and SQL backend behavior -- change discovery ordering -- change replay/idempotency -- startup migration flow -- install/upgrade/downgrade lifecycle at the schema level +## Repository Layout -## 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) +```text +bstore-j/ +├── src/ +├── build.gradle +├── extra.gradle +└── README.md +``` ## License GNU Lesser General Public License, Version 3.0 -