Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
640b301
Add shared SQL backend logger
BenCodez Sep 13, 2026
0840e97
Add shared SQL user schema
BenCodez Sep 13, 2026
af8c3bc
Add shared SQL backend lifecycle
BenCodez Sep 13, 2026
1e18b18
Implement shared JDBC user storage
BenCodez Sep 13, 2026
6de1900
Add headless SQLite user backend
BenCodez Sep 13, 2026
52917ab
Add headless MySQL user backend
BenCodez Sep 13, 2026
afdaba6
Test headless SQLite persistence lifecycle
BenCodez Sep 13, 2026
fe71042
Add explicit SQL backend construction factory
BenCodez Sep 13, 2026
01ecf07
Add SQLite JDBC for headless persistence tests
BenCodez Sep 13, 2026
7267c96
Fix SQL dialect, boolean encoding, and quoted user column access
BenCodez Sep 13, 2026
ff16ad3
Derive user SQL dialect from the provider and retain PostgreSQL UUID …
BenCodez Sep 13, 2026
71d6880
Escape SQLite identifiers consistently during schema setup and enumer…
BenCodez Sep 13, 2026
4fccbe0
Test real SQLite boolean compatibility and quoted schema CRUD across …
BenCodez Sep 13, 2026
3de7926
Cover PostgreSQL CRUD and provider dialect selection without a live d…
BenCodez Sep 13, 2026
4d619a7
Fix SQL backend UUID migration and SQLite shutdown lifecycle
BenCodez Sep 13, 2026
cc6e47c
Preserve bulk-copy identity and committed SQL write outcomes
BenCodez Sep 13, 2026
ef89541
Fix checked-exception rethrow in SQL write cleanup
BenCodez Sep 13, 2026
801fb0a
Preserve declared column definitions during SQL schema expansion
BenCodez Sep 13, 2026
158c8a1
Fix required-column user creation and concurrent SQL schema expansion
BenCodez Sep 13, 2026
7e57c11
Account for existing SimpleAPI CREATE cleanup in schema race tests
BenCodez Sep 13, 2026
79d689f
Fix remaining SQL schema and PostgreSQL write review findings
BenCodez Sep 13, 2026
1de42f0
Align SQL regression fixtures with locking and SimpleAPI cleanup
BenCodez Sep 13, 2026
d308470
Preserve SQL schema identity and bound enumeration
BenCodez Sep 13, 2026
2f9dedd
Update PostgreSQL case-rename regression
BenCodez Sep 13, 2026
05b3d26
Fix native booleans and streamed user enumeration
BenCodez Sep 13, 2026
bd8c350
Page SQL user enumeration outside callback resources
BenCodez Sep 13, 2026
b9a4c35
Fix SQLite paging compile typo
BenCodez Sep 13, 2026
c4a1a1e
Preserve raw MySQL enumeration cursor values
BenCodez Sep 13, 2026
8be88c3
Fix SQL batch and boolean review findings
BenCodez Sep 13, 2026
ea68d09
Drain SQLite operations before closing
BenCodez Sep 13, 2026
faf4c55
Reject new SQLite work while draining active callbacks
BenCodez Sep 13, 2026
888eb42
Update SQL regressions for review fixes
BenCodez Sep 13, 2026
558d6b6
Fix SQL lifecycle review follow-ups
BenCodez Sep 13, 2026
6a7a8d1
Reject ambiguous SQL batch aliases
BenCodez Sep 13, 2026
0747a5c
Update SQLite alias regression expectations
BenCodez Sep 13, 2026
765d4e1
Close SQLite admission race
BenCodez Sep 13, 2026
ccf8064
Fix SQL schema and insert follow-ups
BenCodez Sep 13, 2026
5c0fddb
Fix PostgreSQL bit boolean binding
BenCodez Sep 13, 2026
d469090
Migrate narrow MySQL UUID columns
BenCodez Sep 13, 2026
0bbe368
Harden SQL decoding and diagnostics
BenCodez Sep 13, 2026
fbcff00
Preserve legacy SQL write compatibility
BenCodez Sep 13, 2026
7bdd690
Preserve canonical SQL user identities
BenCodez Sep 13, 2026
f63dbd4
Validate retained SQL identity and boolean schemas
BenCodez Sep 13, 2026
96ef5e0
Harden retained SQL schema compatibility
BenCodez Sep 14, 2026
643d0fe
Harden SQL metadata type handling
BenCodez Sep 14, 2026
8ef1a22
Honor retained MySQL storage types
BenCodez Sep 14, 2026
3bf3305
Harden retained SQL schema migration
BenCodez Sep 14, 2026
c91e273
Preserve retained SQL column attributes
BenCodez Sep 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions AdvancedCore/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,12 @@
<version>5.22.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.53.4.0</version>
<scope>test</scope>
</dependency>
Comment thread
coderabbitai[bot] marked this conversation as resolved.
<dependency>
<groupId>com.nickuc.login</groupId>
<artifactId>api</artifactId>
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.bencodez.advancedcore.core.user.storage.sql;

public interface SqlBackendLogger {
SqlBackendLogger NO_OP = new SqlBackendLogger() {
@Override public void info(String message) {}
@Override public void warn(String message, Throwable error) {}
};

void info(String message);

void warn(String message, Throwable error);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.bencodez.advancedcore.core.user.storage.sql;

import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.function.Consumer;

import com.bencodez.advancedcore.api.user.UserStorage;
import com.bencodez.advancedcore.core.user.storage.SqlUserStorage;

public interface SqlUserBackend extends AutoCloseable {
/** Materialized compatibility API is intentionally bounded by concrete SQL backends. */
int MAX_MATERIALIZED_USERS = 100_000;

UserStorage storageType();

SqlUserStorage user(UUID uuid);

List<UUID> enumerateUsers();

/**
* Streaming enumeration for large historical user tables. Concrete SQL backends
* override this to avoid first materializing every UUID in heap.
*/
default void forEachUser(Consumer<UUID> consumer) {
Objects.requireNonNull(consumer, "consumer");
enumerateUsers().forEach(consumer);
}

boolean isOpen();

@Override
void close();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.bencodez.advancedcore.core.user.storage.sql;

import java.nio.file.Path;
import java.util.Collection;
import java.util.Objects;

import com.bencodez.advancedcore.api.user.usercache.keys.UserDataKey;
import com.bencodez.simpleapi.sql.mysql.config.MysqlConfig;

/**
* Constructs SQL user backends from explicit platform-neutral inputs. Native
* platform adapters are responsible for translating their configuration and
* data-directory concepts before calling this factory.
*/
public final class SqlUserBackendFactory {
private SqlUserBackendFactory() {
}

public static SqliteUserBackend sqlite(Path dataDirectory, String databaseName, String tableName,
Collection<? extends UserDataKey> keys, SqlBackendLogger logger) {
Objects.requireNonNull(keys, "keys");
return new SqliteUserBackend(dataDirectory, databaseName, tableName, SqlUserSchema.fromKeys(keys), logger);
}

public static MysqlUserBackend mysql(String baseTableName, MysqlConfig config,
Collection<? extends UserDataKey> keys, SqlBackendLogger logger) {
Objects.requireNonNull(keys, "keys");
return new MysqlUserBackend(baseTableName, config, SqlUserSchema.fromKeys(keys), logger);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.bencodez.advancedcore.core.user.storage.sql;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;

import com.bencodez.advancedcore.api.user.usercache.keys.UserDataKey;
import com.bencodez.advancedcore.api.user.usercache.keys.UserDataKeyBoolean;
import com.bencodez.advancedcore.api.user.usercache.keys.UserDataKeyInt;
import com.bencodez.simpleapi.sql.DataType;

public final class SqlUserSchema {
public static final String UUID_COLUMN = "uuid";

public record ColumnDefinition(String name, String sqlType, DataType dataType) {
public ColumnDefinition {
Objects.requireNonNull(name, "name");
Objects.requireNonNull(sqlType, "sqlType");
Objects.requireNonNull(dataType, "dataType");
if (name.isBlank()) throw new IllegalArgumentException("Column name cannot be blank");
if (sqlType.isBlank()) throw new IllegalArgumentException("SQL type cannot be blank");
}
}

private final Map<String, ColumnDefinition> columnsByLowerName;

private SqlUserSchema(Map<String, ColumnDefinition> columnsByLowerName) {
this.columnsByLowerName = Collections.unmodifiableMap(new LinkedHashMap<>(columnsByLowerName));
}

public static Builder builder() { return new Builder(); }

public static SqlUserSchema fromKeys(Collection<? extends UserDataKey> keys) {
Builder builder = builder();
for (UserDataKey key : Objects.requireNonNull(keys, "keys")) {
DataType type = DataType.STRING;
if (key instanceof UserDataKeyInt) type = DataType.INTEGER;
else if (key instanceof UserDataKeyBoolean) type = DataType.BOOLEAN;
builder.column(key.getKey(), key.getColumnType(), type);
}
return builder.build();
}

public List<ColumnDefinition> columns() { return new ArrayList<>(columnsByLowerName.values()); }

public ColumnDefinition column(String name) {
if (name == null) return null;
return columnsByLowerName.get(name.toLowerCase(Locale.ROOT));
}

public boolean contains(String name) { return column(name) != null; }

public static final class Builder {
private final Map<String, ColumnDefinition> columns = new LinkedHashMap<>();

private Builder() {
columns.put(UUID_COLUMN, new ColumnDefinition(UUID_COLUMN, "VARCHAR(37)", DataType.STRING));
}

public Builder column(String name, String sqlType, DataType dataType) {
Objects.requireNonNull(name, "name");
if (UUID_COLUMN.equalsIgnoreCase(name)) {
throw new IllegalArgumentException("Column name 'uuid' is reserved for user identity");
}
String canonical = name.toLowerCase(Locale.ROOT);
ColumnDefinition existing = columns.get(canonical);
if (existing != null) {
throw new IllegalArgumentException("Duplicate SQL column name: " + name + " conflicts with " + existing.name());
}
columns.put(canonical, new ColumnDefinition(name, sqlType, dataType));
return this;
}

public SqlUserSchema build() { return new SqlUserSchema(columns); }
}
}
Loading
Loading