### Quick Start: Initialize and Use Architect Source: https://github.com/w8fyz/architect/blob/main/README.md A basic example demonstrating how to initialize Architect, set database credentials, register an entity, start the service, and perform basic CRUD operations using GenericRepository. ```java Architect architect = new Architect() .setReceiver(true) .setDatabaseCredentials(new DatabaseCredentials( new PostgreSQLAuth("localhost", 5432, "mydb"), "user", "password", 10 )); architect.addEntityClass(User.class); architect.start(); GenericRepository users = new GenericRepository<>(User.class); User user = new User("John", "john@example.com", 25); users.save(user); User found = users.query() .where("email", "john@example.com") .findFirst(); architect.stop(); ``` -------------------------------- ### Full Application Setup with Architect Source: https://context7.com/w8fyz/architect/llms.txt This snippet shows the complete setup for an Architect application, including database and cache configuration, entity registration, starting the framework, initializing repositories, running migrations in production, and application logic execution. ```java import sh.fyz.architect.Architect; import sh.fyz.architect.persistent.DatabaseCredentials; import sh.fyz.architect.cache.RedisCredentials; import sh.fyz.architect.persistent.sql.provider.PostgreSQLAuth; import sh.fyz.architect.persistent.sql.TlsMode; import sh.fyz.architect.migration.MigrationManager; import sh.fyz.architect.repositories.GenericRepository; import sh.fyz.architect.repositories.GenericCachedRepository; import sh.fyz.architect.repositories.QueryBuilder.SortOrder; import java.nio.file.Path; public class Application { private static Architect architect; private static UserRepository users; private static ProductRepository products; public static void main(String[] args) { // Configure Architect architect = new Architect() .setReceiver(true) .setDatabaseCredentials(new DatabaseCredentials( new PostgreSQLAuth("localhost", 5432, "myapp") .withTls(TlsMode.PREFER), "appuser", "secret", 20, 10, "update" )) .setRedisCredentials(new RedisCredentials( "localhost", "", 6379, 2000, 50, 3600 )); // Register entities architect.addEntityClass(User.class); architect.addEntityClass(Product.class); architect.addEntityClass(Order.class); // Start framework architect.start(); // Initialize repositories users = new UserRepository(); products = new ProductRepository(); try { // Run migrations in production if (isProduction()) { MigrationManager migrations = new MigrationManager( architect, Path.of("./migrations") ); migrations.executeMigration("v1_initial"); } // Application logic runApplication(); } finally { // Graceful shutdown architect.stop(); } } private static void runApplication() { // Create users User admin = new User("admin@example.com", "Admin User"); admin.setCountry("USA"); admin = users.save(admin); // Query users List usaUsers = users.findActiveByCountry("USA"); User found = users.findByEmail("admin@example.com"); // Create products (cached) Product laptop = new Product(); laptop.setName("MacBook Pro"); laptop.setPrice(2499.99); laptop.setCategory("Electronics"); laptop = products.save(laptop); // Query products from cache List electronics = products.findAvailableByCategory("Electronics"); List affordable = products.findInPriceRange(100, 500); // Complex queries List searchResults = users.query() .whereLike("name", "%Admin%") .where("active", true) .orderBy("createdAt", SortOrder.DESC) .limit(10) .findAll(); long activeCount = users.query() .where("active", true) .count(); System.out.println("Active users: " + activeCount); System.out.println("Electronics products: " + electronics.size()); } private static boolean isProduction() { return "production".equals(System.getenv("APP_ENV")); } } // Custom repositories class UserRepository extends GenericRepository { public UserRepository() { super(User.class); } public User findByEmail(String email) { return query().where("email", email).findFirst(); } public List findActiveByCountry(String country) { return query() .where("country", country) .where("active", true) .orderBy("name") .findAll(); } } class ProductRepository extends GenericCachedRepository { public ProductRepository() { super(Product.class); } public List findAvailableByCategory(String category) { return query() .where("category", category) .where("available", true) .findAll(); } public List findInPriceRange(double min, double max) { return query() .where("price", Operator.GTE, min) .where("price", Operator.LTE, max) .orderBy("price") .findAll(); } } ``` -------------------------------- ### Bootstrap Architect with Database Credentials Source: https://github.com/w8fyz/architect/blob/main/SKILL.md Initialize the Architect framework, configure database connection details using DatabaseCredentials, and start the service. Add entity classes before starting. ```java import sh.fyz.architect.Architect; import sh.fyz.architect.entities.IdentifiableEntity; import sh.fyz.architect.persistent.DatabaseCredentials; import sh.fyz.architect.persistent.sql.PostgreSQLAuth; // ... other imports ... Architect architect = new Architect() .setReceiver(true) .setDatabaseCredentials(new DatabaseCredentials( new PostgreSQLAuth("localhost", 5432, "mydb"), "user", "password", 10, 10, "update" )); architect.addEntityClass(User.class); architect.start(); // ... use repositories ... architect.stop(); ``` -------------------------------- ### Basic Architect Configuration and Startup Source: https://context7.com/w8fyz/architect/llms.txt Configure Architect with database credentials, register entity classes, and start the framework. Ensure graceful shutdown using architect.stop(). ```java import sh.fyz.architect.Architect; import sh.fyz.architect.persistent.DatabaseCredentials; import sh.fyz.architect.cache.RedisCredentials; import sh.fyz.architect.persistent.sql.provider.PostgreSQLAuth; import sh.fyz.architect.persistent.sql.TlsMode; // Basic PostgreSQL setup Architect architect = new Architect() .setReceiver(true) // This instance handles DB writes .setDatabaseCredentials(new DatabaseCredentials( new PostgreSQLAuth("localhost", 5432, "mydb"), "dbuser", // username "dbpassword", // password 10, // connection pool size 10, // thread pool size "update" // hbm2ddl: none, validate, update, create, create-drop )); // Register entity classes architect.addEntityClass(User.class); architect.addEntityClass(Product.class); architect.addEntityClass(Order.class); // Start the framework architect.start(); // ... application logic ... // Shutdown gracefully architect.stop(); ``` -------------------------------- ### Configure and Start GenericRelayRepository Source: https://github.com/w8fyz/architect/blob/main/README.md Set up a non-receiver instance of Architect for distributed operations using Redis pub/sub. Ensure Redis credentials are provided. ```java Architect architect = new Architect() .setReceiver(false) .setRedisCredentials(new RedisCredentials(...)); architect.start(); GenericRelayRepository users = new GenericRelayRepository<>(User.class); users.save(user); // sent via Redis pub/sub to the receiver ``` -------------------------------- ### List and Read Migration Content in Java Source: https://github.com/w8fyz/architect/blob/main/README.md Get a list of all available migration file names and read the SQL content of a specific migration file. ```java List files = manager.listMigrations(); String sql = manager.readMigrationContent("v1_init"); ``` -------------------------------- ### Custom UserRepository Example Source: https://github.com/w8fyz/architect/blob/main/SKILL.md Demonstrates creating a custom repository for the User entity, centralizing query logic for specific finders like findByEmail and findActiveByCountry. This pattern is also compatible with GenericCachedRepository and GenericRelayRepository. ```java public class UserRepository extends GenericRepository { public UserRepository() { super(User.class); } public User findByEmail(String email) { return query().where("email", email).findFirst(); } public List findActiveByCountry(String country) { return query() .where("country", country) .where("active", true) .orderBy("createdAt", SortOrder.DESC) .findAll(); } public List search(String keyword, int page, int pageSize) { return query() .whereLike("name", "%" + keyword + "%") .orderBy("name") .limit(pageSize) .offset(page * pageSize) .findAll(); } } ``` -------------------------------- ### Get Table Data with Pagination Source: https://context7.com/w8fyz/architect/llms.txt Retrieve data from a table using MigrationManager, specifying the page number and the number of rows per page. This method is useful for handling large datasets efficiently. The example also shows how to paginate through all data by iterating through pages until all rows are processed. ```java // GET TABLE DATA WITH PAGINATION TableData data = manager.getTableData("users", 0, 50); // page 0, 50 rows per page System.out.printf("Table: %s, Total rows: %d, Page: %d%n", data.tableName(), data.totalRows(), data.page()); System.out.println("Columns: " + String.join(", ", data.columnNames())); for (List row : data.rows()) { System.out.println(String.join(" | ", row)); } // Paginate through all data int page = 0; int pageSize = 100; long total = manager.getTableData("orders", 0, 1).totalRows(); while (page * pageSize < total) { TableData pageData = manager.getTableData("orders", page, pageSize); processRows(pageData.rows()); page++; } ``` -------------------------------- ### GenericRepository CRUD and Async Operations Source: https://github.com/w8fyz/architect/blob/main/README.md Provides examples of standard CRUD operations (save, findById, all, delete) and their asynchronous counterparts using `GenericRepository` for entity management. ```java GenericRepository users = new GenericRepository<>(User.class); // CRUD User saved = users.save(user); User found = users.findById(1L); List all = users.all(); users.delete(user); // Async variants users.saveAsync(user, onSuccess, onError); users.findByIdAsync(1L, onSuccess, onError); users.allAsync(onSuccess, onError); users.deleteAsync(user, onSuccess, onError); ``` -------------------------------- ### Initialize and Use MigrationManager Source: https://context7.com/w8fyz/architect/llms.txt Sets up the MigrationManager for schema migration tasks after Architect has been started. It supports DDL generation, migration file creation, listing, reading, and execution. ```java import sh.fyz.architect.migration.MigrationManager; import sh.fyz.architect.migration.DatabaseInspector.*; import java.nio.file.Path; import java.util.List; // Initialize after Architect.start() Architect architect = new Architect() .setDatabaseCredentials(dbCreds); architect.addEntityClass(User.class); architect.addEntityClass(Product.class); architect.addEntityClass(Order.class); architect.start(); MigrationManager manager = new MigrationManager(architect, Path.of("./migrations")); // GENERATE SCHEMA - Preview DDL without writing file String ddl = manager.generateSchema(); System.out.println("Generated DDL:\n" + ddl); // CREATE MIGRATION - Generate and save schema snapshot Path migrationFile = manager.createMigration("v1_initial_schema"); System.out.println("Created: " + migrationFile); // Output: migrations/v1_initial_schema.sql // LIST MIGRATIONS List migrations = manager.listMigrations(); migrations.forEach(m -> System.out.println("Available: " + m)); // Output: v1_initial_schema.sql, v2_add_orders.sql, ... // READ MIGRATION CONTENT String content = manager.readMigrationContent("v1_initial_schema"); System.out.println(content); // EXECUTE MIGRATION - Run SQL file in transaction manager.executeMigration("v1_initial_schema"); // EXECUTE RAW SQL manager.executeSql("ALTER TABLE users ADD COLUMN phone VARCHAR(20)"); manager.executeSql(""" CREATE INDEX idx_users_email ON users(email); CREATE INDEX idx_users_country ON users(country); """); // CLEAR DATABASE - Requires confirmation token manager.clearDatabase(MigrationManager.CLEAR_CONFIRMATION); // "CONFIRM_DROP_ALL" ``` -------------------------------- ### Inspect Database Tables in Java Source: https://github.com/w8fyz/architect/blob/main/README.md Retrieve information about database tables. This includes listing all tables, getting the schema for a specific table, and fetching table data within a specified range. ```java List tables = manager.listTables(); TableSchema schema = manager.getTableSchema("users"); TableData data = manager.getTableData("users", 0, 50); ``` -------------------------------- ### Define a JPA Entity for Architect Source: https://github.com/w8fyz/architect/blob/main/README.md Example of a User entity that implements IdentifiableEntity, includes JPA annotations for table mapping and ID generation, and provides constructors. ```java @Entity @Table(name = "users") public class User implements IdentifiableEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; private int age; public User() {} public User(String name, String email, int age) { this.name = name; this.email = email; this.age = age; } @Override public Long getId() { return id; } // getters and setters... } ``` -------------------------------- ### Open Migration GUI in Java Source: https://github.com/w8fyz/architect/blob/main/README.md Launch the graphical user interface for the migration tool during development. This provides an interactive way to manage schema migrations. ```java MigrationToolGUI.open(architect, Path.of("./migrations")); ``` -------------------------------- ### Configure Architect Instance with Database and Redis Source: https://github.com/w8fyz/architect/blob/main/README.md Demonstrates comprehensive configuration of an Architect instance, including setting it as a receiver, configuring database credentials with connection and thread pool sizes, and optionally setting up Redis credentials with a default TTL. ```java Architect architect = new Architect(); // Required: this instance writes to the database architect.setReceiver(true); // Required: database connection architect.setDatabaseCredentials(new DatabaseCredentials( new PostgreSQLAuth("localhost", 5432, "mydb"), "user", "password", 10, // connection pool size 10, // thread pool size "update" // hbm2ddl.auto strategy )); // Optional: Redis for caching / relay architect.setRedisCredentials(new RedisCredentials( "localhost", "password", 6379, 2000, 10 )); // Register entity classes architect.addEntityClass(User.class); architect.addEntityClass(Product.class); architect.start(); ``` -------------------------------- ### Initialize and Use GenericRelayRepository Source: https://context7.com/w8fyz/architect/llms.txt Demonstrates setting up both receiver and non-receiver Architect instances for distributed data operations. The receiver handles database writes, while non-receiver instances relay operations via Redis. ```java import sh.fyz.architect.repositories.GenericRelayRepository; import sh.fyz.architect.Architect; // RECEIVER INSTANCE (handles actual DB writes) Architect receiver = new Architect() .setReceiver(true) // This instance writes to DB .setDatabaseCredentials(dbCreds) .setRedisCredentials(redisCreds); receiver.addEntityClass(Order.class); receiver.start(); // Use cached repository on receiver GenericCachedRepository receiverRepo = new GenericCachedRepository<>(Order.class); // NON-RECEIVER INSTANCE (relays via pub/sub) Architect relay = new Architect() .setReceiver(false) // This instance does NOT write directly to DB .setDatabaseCredentials(dbCreds) .setRedisCredentials(redisCreds); relay.addEntityClass(Order.class); relay.start(); // Use relay repository on non-receiver instances GenericRelayRepository relayRepo = new GenericRelayRepository<>(Order.class); // Operations are relayed to the receiver via Redis pub/sub Order order = new Order(); order.setStatus("pending"); order.setTotal(150.00); // This publishes to Redis channel, receiver picks up and persists Order saved = relayRepo.save(order); // Reads work from cache as normal Order found = relayRepo.findById(1L); List allOrders = relayRepo.all(); // Deletes are also relayed relayRepo.delete(order); ``` ```java // Custom relay repository public class OrderRepository extends GenericRelayRepository { public OrderRepository() { super(Order.class); } public List findPendingOrders() { return query() .where("status", "pending") .orderBy("createdAt", SortOrder.ASC) .findAll(); } } ``` -------------------------------- ### Configure DatabaseCredentials with Full Control Source: https://github.com/w8fyz/architect/blob/main/README.md Illustrates the full constructor for `DatabaseCredentials`, allowing explicit control over connection pool size, thread pool size, and the `hbm2ddl.auto` strategy. ```java // Minimal (defaults: threadPoolSize=10, hbm2ddl="update") new DatabaseCredentials(provider, user, password, poolSize) // Full control new DatabaseCredentials(provider, user, password, poolSize, threadPoolSize, hbm2ddlAuto) ``` -------------------------------- ### Generate and Create Migration in Java Source: https://github.com/w8fyz/architect/blob/main/README.md Generate a SQL schema snapshot and create a new migration file. The generated DDL can be previewed before saving. ```java String ddl = manager.generateSchema(); // preview the DDL Path file = manager.createMigration("v1_init"); // saves to ./migrations/v1_init.sql ``` -------------------------------- ### QueryBuilder: Pagination Implementation Source: https://github.com/w8fyz/architect/blob/main/README.md Configures limit and offset for paginating query results, showing how to retrieve specific pages of data. ```java query().limit(10) // first 10 results query().limit(10).offset(20) // page 3 (10 per page) query() .where("active", true) .orderBy("createdAt", SortOrder.DESC) .limit(25) .offset(0) .findAll(); ``` -------------------------------- ### Configure RedisCredentials with Default TTL Source: https://github.com/w8fyz/architect/blob/main/README.md Demonstrates setting a default Time-To-Live (TTL) in seconds for cached entities when configuring `RedisCredentials`. A value of 0 means no expiry. ```java new RedisCredentials("localhost", "password", 6379, 2000, 10, /* defaultTtlSeconds */ 3600) ``` -------------------------------- ### List and Read Migration Files Source: https://github.com/w8fyz/architect/blob/main/SKILL.md Retrieves a list of all available migration file names and reads the raw SQL content of a specific migration file. This is useful for reviewing migration scripts before execution. ```java List files = manager.listMigrations(); // ["v1_init.sql", "v2_add_orders.sql"] String content = manager.readMigrationContent("v1_init"); // raw SQL content ``` -------------------------------- ### Configure TLS for Network SQL Providers Source: https://github.com/w8fyz/architect/blob/main/README.md Shows how to enable TLS encryption for network-based SQL providers like PostgreSQL and MySQL using the `withTls` method and specifying the desired `TlsMode`. ```java new PostgreSQLAuth("db.example.com", 5432, "app").withTls(TlsMode.REQUIRE) new MySQLAuth("db.example.com", 3306, "app").withTls(TlsMode.VERIFY_FULL) ``` -------------------------------- ### Generate and Create Migration File Source: https://github.com/w8fyz/architect/blob/main/SKILL.md Generates the Data Definition Language (DDL) for the current entity definitions as a string and creates a new migration SQL file in the specified directory. The generated SQL is a full schema snapshot. ```java String ddl = manager.generateSchema(); // DDL as string (preview) Path file = manager.createMigration("v1_init"); // writes ./migrations/v1_init.sql ``` -------------------------------- ### Use Custom UserRepository Instance Source: https://github.com/w8fyz/architect/blob/main/README.md Instantiate and utilize custom repository methods for data retrieval and operations. ```java UserRepository users = new UserRepository(); User john = users.findByEmail("john@example.com"); List adults = users.findAdults(); List page2 = users.search("doe", 1, 25); ``` -------------------------------- ### Implement GenericCachedRepository for Product Data Source: https://context7.com/w8fyz/architect/llms.txt Extend GenericCachedRepository to provide Redis-first caching for Product entities. Writes are queued for batch database flushing, and reads check the cache before falling back to the database. ```java import sh.fyz.architect.repositories.GenericCachedRepository; import sh.fyz.architect.entities.IdentifiableEntity; // Entity must implement IdentifiableEntity public class Product implements IdentifiableEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private double price; private String category; private boolean available; public Product() {} @Override public Long getId() { return id; } // getters/setters... } ``` ```java // Create cached repository GenericCachedRepository productRepo = new GenericCachedRepository<>(Product.class); // SAVE - Writes to Redis immediately, queues DB write Product product = new Product(); product.setName("Laptop"); product.setPrice(999.99); product.setCategory("Electronics"); product.setAvailable(true); Product saved = productRepo.save(product); // FIND BY ID - Checks Redis first, falls back to DB Product found = productRepo.findById(saved.getId()); // ALL - Returns from cache if populated List allProducts = productRepo.all(); // QUERIES - Execute against cache when possible List electronics = productRepo.query() .where("category", "Electronics") .where("available", true) .orderBy("price", SortOrder.ASC) .findAll(); // FLUSH - Manually trigger database sync (normally automatic via background pool) productRepo.flushUpdates(); ``` ```java // Custom cached repository public class ProductRepository extends GenericCachedRepository { public ProductRepository() { super(Product.class); } public List findAvailableByCategory(String category) { return query() .where("category", category) .where("available", true) .orderBy("name") .findAll(); } public List findInPriceRange(double min, double max) { return query() .where("price", Operator.GTE, min) .where("price", Operator.LTE, max) .findAll(); } } ``` -------------------------------- ### List Tables and Inspect Schema Source: https://context7.com/w8fyz/architect/llms.txt Use MigrationManager to list all tables in the database and retrieve schema details for a specific table. This includes column information, data types, nullability, primary keys, default values, and foreign key constraints. ```java import sh.fyz.architect.migration.MigrationManager; import sh.fyz.architect.migration.DatabaseInspector.*; import java.util.List; MigrationManager manager = new MigrationManager(architect, Path.of("./migrations")); // LIST ALL TABLES List tables = manager.listTables(); for (TableInfo table : tables) { System.out.printf("Table: %s, Columns: %d, Rows: %d%n", table.name(), table.columnCount(), table.rowCount()); } // Output: // Table: users, Columns: 6, Rows: 1250 // Table: products, Columns: 5, Rows: 500 // Table: orders, Columns: 8, Rows: 3200 // GET TABLE SCHEMA TableSchema schema = manager.getTableSchema("users"); System.out.println("Table: " + schema.tableName()); System.out.println("Columns:"); for (ColumnInfo col : schema.columns()) { System.out.printf(" %s %s(%d) %s %s %s%n", col.name(), col.type(), col.size(), col.nullable() ? "NULL" : "NOT NULL", col.primaryKey() ? "PK" : "", col.defaultValue() != null ? "DEFAULT " + col.defaultValue() : ""); } System.out.println("Foreign Keys:"); for (ForeignKeyInfo fk : schema.foreignKeys()) { System.out.printf(" %s -> %s.%s (%s)%n", fk.columnName(), fk.referencedTable(), fk.referencedColumn(), fk.constraintName()); } ``` -------------------------------- ### Define Custom UserRepository with Query Methods Source: https://github.com/w8fyz/architect/blob/main/README.md Create a custom repository extending GenericRepository to centralize and reuse entity-specific query logic. Includes methods for finding by email, adults, active users, searching, counting, and deactivating. ```java public class UserRepository extends GenericRepository { public UserRepository() { super(User.class); } public User findByEmail(String email) { return query().where("email", email).findFirst(); } public List findAdults() { return query() .where("age", Operator.GTE, 18) .orderBy("name") .findAll(); } public List findActiveByCountry(String country) { return query() .where("country", country) .where("active", true) .orderBy("createdAt", SortOrder.DESC) .findAll(); } public List search(String keyword, int page, int pageSize) { return query() .whereLike("name", "%" + keyword + "%") .orderBy("name") .limit(pageSize) .offset(page * pageSize) .findAll(); } public long countByRole(String role) { return query().where("role", role).count(); } public int deactivateUnverified() { return query() .where("verified", false) .whereRaw("createdAt < :cutoff", Map.of("cutoff", someDateValue)) .delete(); } } ``` -------------------------------- ### Generic Repository CRUD Operations Source: https://github.com/w8fyz/architect/blob/main/SKILL.md Illustrates basic Create, Read, Update, and Delete (CRUD) operations using the GenericRepository. Asynchronous equivalents like saveAsync, findByIdAsync, allAsync, and deleteAsync are also available. ```java var repo = new GenericRepository<>(User.class); User saved = repo.save(user); User found = repo.findById(1L); List all = repo.all(); repo.delete(user); ``` -------------------------------- ### Execute Migration in Java Source: https://github.com/w8fyz/architect/blob/main/README.md Execute a specific migration file. All SQL statements within the file are run in a single transaction, with automatic rollback on error. ```java manager.executeMigration("v1_init"); ``` -------------------------------- ### QueryBuilder: Equality and Comparison Filtering Source: https://github.com/w8fyz/architect/blob/main/README.md Demonstrates basic filtering using exact matches and comparison operators (EQ, NEQ, GT, GTE, LT, LTE) on repository queries. ```java // Equality query().where("name", "John") // Comparison operators: EQ, NEQ, GT, GTE, LT, LTE query().where("age", Operator.GTE, 18) ``` -------------------------------- ### Initialize GenericCachedRepository Source: https://github.com/w8fyz/architect/blob/main/README.md Instantiate a GenericCachedRepository for Redis-first reads with database fallback. It supports relation resolution from cache. ```java GenericCachedRepository users = new GenericCachedRepository<>(User.class); ``` -------------------------------- ### MigrationManager Initialization Source: https://github.com/w8fyz/architect/blob/main/SKILL.md Initializes the MigrationManager, specifying the Architect instance and the directory where migration SQL files are stored. The migration system handles schema generation, execution, and database inspection. ```java MigrationManager manager = new MigrationManager(architect, Path.of("./migrations")); ``` -------------------------------- ### Database Credentials with TLS Configuration Source: https://context7.com/w8fyz/architect/llms.txt Configure secure database connections using TLS for PostgreSQL, MySQL, and MariaDB. Supports different TLS modes and fallback to non-TLS for H2 and SQLite. ```java import sh.fyz.architect.persistent.DatabaseCredentials; import sh.fyz.architect.persistent.sql.provider.*; import sh.fyz.architect.persistent.sql.TlsMode; // PostgreSQL with TLS verification DatabaseCredentials postgresSecure = new DatabaseCredentials( new PostgreSQLAuth("db.example.com", 5432, "production") .withTls(TlsMode.VERIFY_FULL), "admin", "secret", 20, 15, "none" ); // MySQL with TLS required DatabaseCredentials mysqlSecure = new DatabaseCredentials( new MySQLAuth("mysql.example.com", 3306, "appdb") .withTls(TlsMode.REQUIRE), "root", "password", 10 ); // MariaDB with CA verification DatabaseCredentials mariaSecure = new DatabaseCredentials( new MariaDBAuth("mariadb.example.com", 3306, "store") .withTls(TlsMode.VERIFY_CA), "user", "pass", 15, 10, "validate" ); // H2 in-memory database (no TLS) DatabaseCredentials h2Memory = new DatabaseCredentials( new H2Auth("mem:testdb"), "sa", "", 5 ); // SQLite file database (no TLS) DatabaseCredentials sqlite = new DatabaseCredentials( new SQLiteAuth("/var/data/app.db"), "", "", 1 ); ``` -------------------------------- ### Async Query Operations Source: https://context7.com/w8fyz/architect/llms.txt Demonstrates asynchronous query execution using CompletableFuture for non-blocking operations. ```java // Async query operations with CompletableFuture repo.query() .where("country", "USA") .findAllAsync() .thenAccept(users -> System.out.println("Found " + users.size() + " US users")); repo.query() .where("email", "admin@example.com") .findFirstAsync() .thenAccept(admin -> System.out.println("Admin: " + admin.getName())); repo.query() .where("active", true) .countAsync() .thenAccept(count -> System.out.println("Active users: " + count)); ``` -------------------------------- ### Multiple Conditions Query Source: https://context7.com/w8fyz/architect/llms.txt Builds a query with multiple conditions, which are AND-ed together, to find active users in a specific country. ```java // Multiple conditions (AND-ed together) List activeUsUsers = repo.query() .where("country", "USA") .where("active", true) .findAll(); ``` -------------------------------- ### Simple Equality Query Source: https://context7.com/w8fyz/architect/llms.txt Constructs a simple equality query to find a single user by email. Access the QueryBuilder via repo.query(). ```java import sh.fyz.architect.repositories.GenericRepository; import sh.fyz.architect.repositories.QueryBuilder; import sh.fyz.architect.repositories.QueryBuilder.Operator; import sh.fyz.architect.repositories.QueryBuilder.SortOrder; import java.util.List; import java.util.Map; GenericRepository repo = new GenericRepository<>(User.class); // Simple equality query User user = repo.query() .where("email", "john@example.com") .findFirst(); ``` -------------------------------- ### Pagination Source: https://context7.com/w8fyz/architect/llms.txt Implements pagination by setting a limit and offset to retrieve a specific subset of records, ordered by name. ```java // Pagination int page = 0; int pageSize = 20; List pagedUsers = repo.query() .where("active", true) .orderBy("name", SortOrder.ASC) .limit(pageSize) .offset(page * pageSize) .findAll(); ``` -------------------------------- ### Register Repositories with RepositoryRegistry Source: https://github.com/w8fyz/architect/blob/main/README.md Add generic repositories to the Architect instance for cross-repository lookups, essential for relation resolution in cached and relay repositories. ```java architect.addRepositories( new GenericRepository<>(User.class), new GenericRepository<>(Product.class) ); // Manual access RepositoryRegistry.get().getRepository("users"); ``` -------------------------------- ### QueryBuilder: Pattern Matching and Set Membership Filtering Source: https://github.com/w8fyz/architect/blob/main/README.md Illustrates filtering with pattern matching (LIKE) and checking for values within or outside a specified set. ```java // Pattern matching query().whereLike("name", "John%") // Set membership query().whereIn("category", List.of("A", "B", "C")) query().whereNotIn("status", List.of("banned", "suspended")) ``` -------------------------------- ### NULL Checks Source: https://context7.com/w8fyz/architect/llms.txt Demonstrates how to query for records where a specific field is either NULL or NOT NULL. ```java // NULL checks List usersWithoutDepartment = repo.query() .whereNull("department") .findAll(); List usersWithDepartment = repo.query() .whereNotNull("department") .findAll(); ``` -------------------------------- ### Execute Migration SQL Source: https://github.com/w8fyz/architect/blob/main/SKILL.md Executes a specific migration script by reading its content from the migration directory or executes arbitrary SQL statements. All statements within a migration are run in a single transaction with automatic rollback on error. ```java manager.executeMigration("v1_init"); // reads & executes ./migrations/v1_init.sql manager.executeSql("ALTER TABLE ..."); // execute arbitrary SQL ``` -------------------------------- ### QueryBuilder: Sorting Options Source: https://github.com/w8fyz/architect/blob/main/README.md Applies sorting to query results in ascending (default) or descending order, and demonstrates multi-column sorting. ```java query().orderBy("name") // ASC (default) query().orderBy("price", SortOrder.DESC) // DESC query().orderBy("category").orderBy("name") // multi-column ``` -------------------------------- ### Raw HQL for Complex Queries Source: https://context7.com/w8fyz/architect/llms.txt Executes complex queries using raw HQL, allowing for custom SQL fragments and parameter binding. ```java // Raw HQL for complex queries List customQuery = repo.query() .where("active", true) .whereRaw("LOWER(name) LIKE :pattern", Map.of("pattern", "%admin%")) .whereRaw("createdAt BETWEEN :start AND :end", Map.of( "start", LocalDateTime.now().minusMonths(6), "end", LocalDateTime.now() )) .findAll(); ``` -------------------------------- ### QueryBuilder Terminal Operations Source: https://github.com/w8fyz/architect/blob/main/SKILL.md Demonstrates terminal operations for executing queries built with QueryBuilder, including fetching lists, single results, counts, and performing deletions. Asynchronous versions return CompletableFuture. ```java List results = query().where(...).findAll(); T first = query().where(...).findFirst(); long count = query().where(...).count(); int deleted = query().where(...).delete(); // requires at least one condition ``` -------------------------------- ### QueryBuilder: Raw HQL Combined with Builder Conditions Source: https://github.com/w8fyz/architect/blob/main/README.md Integrates raw HQL expressions with standard QueryBuilder conditions for advanced and flexible filtering. ```java // Combined with builder conditions query() .where("category", "Electronics") .whereRaw("LENGTH(name) > :len", Map.of("len", 5)) ``` -------------------------------- ### LIKE Pattern Matching Source: https://context7.com/w8fyz/architect/llms.txt Performs LIKE pattern matching on multiple fields to find users whose names and emails match specific patterns. ```java // LIKE pattern matching List matchingUsers = repo.query() .whereLike("name", "%Smith%") .whereLike("email", "%@example.com") .findAll(); ``` -------------------------------- ### Comparison Operators and Sorting Source: https://context7.com/w8fyz/architect/llms.txt Utilizes comparison operators (e.g., Greater Than or Equal To) and sorting to find recent active users. ```java // Comparison operators List recentUsers = repo.query() .where("createdAt", Operator.GTE, LocalDateTime.now().minusDays(7)) .where("active", true) .orderBy("createdAt", SortOrder.DESC) .findAll(); ``` -------------------------------- ### Create a User Entity Source: https://github.com/w8fyz/architect/blob/main/SKILL.md Define a User entity that implements IdentifiableEntity. Ensure it has a no-arg constructor and is annotated with @Entity and @Table. ```java import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Table; import sh.fyz.architect.entities.IdentifiableEntity; @Entity @Table(name = "users") public class User implements IdentifiableEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; public User() {} @Override public Long getId() { return id; } // getters/setters } ``` -------------------------------- ### Redis Credentials Configuration Source: https://context7.com/w8fyz/architect/llms.txt Configure Redis connection for caching and pub/sub. An optional TTL parameter sets a default expiration time for cached entities. ```java import sh.fyz.architect.cache.RedisCredentials; // Basic Redis setup (no TTL - keys persist until explicit deletion) RedisCredentials redis = new RedisCredentials( "localhost", // host "redispassword", // password (empty string if none) 6379, // port 2000, // timeout in milliseconds 50 // max connections ); // Redis with 1-hour TTL on all cached entities RedisCredentials redisWithTtl = new RedisCredentials( "redis.example.com", "secret", 6379, 3000, 100, 3600 // default TTL in seconds (1 hour) ); // Configure Architect with Redis Architect architect = new Architect() .setReceiver(true) .setDatabaseCredentials(dbCredentials) .setRedisCredentials(redisWithTtl); ``` -------------------------------- ### QueryBuilder Conditions and Operators Source: https://github.com/w8fyz/architect/blob/main/SKILL.md Shows how to build complex queries using the QueryBuilder API. Supports various operators like EQ, NEQ, GT, LT, LIKE, IN, and NULL checks. Conditions are automatically ANDed. ```java .where("field", value) // EQ .where("field", Operator.GT, value) // comparison .whereLike("field", "pattern%") .whereIn("field", collection) .whereNotIn("field", collection) .whereNull("field") .whereNotNull("field") .whereRaw("HQL fragment", Map.of("param", val)) // raw HQL with named params (only overload as of 2.2.0) .orderBy("field") // ASC .orderBy("field", SortOrder.DESC) .limit(n) .offset(n) ``` -------------------------------- ### Inspect Database Schema and Data Source: https://github.com/w8fyz/architect/blob/main/SKILL.md Provides methods to inspect the current state of the database, including listing tables with their row and column counts, retrieving the schema details for a specific table, and fetching paginated data from a table. Table names are validated against DatabaseMetaData to prevent SQL injection. ```java List tables = manager.listTables(); // name, columnCount, rowCount TableSchema schema = manager.getTableSchema("users"); // columns, types, PKs, FKs TableData data = manager.getTableData("users", 0, 50); // paginated rows (max 1000) ``` -------------------------------- ### Configure TLS for Database Connection Source: https://github.com/w8fyz/architect/blob/main/SKILL.md Optionally configure Transport Layer Security (TLS) for network-based database connections. SQLite does not support TLS and will throw an exception. ```java new PostgreSQLAuth("db", 5432, "app").withTls(TlsMode.REQUIRE) ``` ```java new MySQLAuth("db", 3306, "app").withTls(TlsMode.VERIFY_FULL) ``` -------------------------------- ### Gradle Dependency for Architect Source: https://github.com/w8fyz/architect/blob/main/SKILL.md Add this dependency to your Gradle build file to include the Architect library. ```groovy dependencies { implementation 'sh.fyz:Architect:2.2.0' } ``` -------------------------------- ### QueryBuilder: Raw HQL with Named Parameters Source: https://github.com/w8fyz/architect/blob/main/README.md Utilizes raw HQL queries with named parameters for complex filtering conditions not directly supported by the builder. ```java // With named parameters query().whereRaw("LOWER(name) = :val", Map.of("val", "john")) // BETWEEN query().whereRaw("price BETWEEN :min AND :max", Map.of("min", 10.0, "max", 100.0)) ``` -------------------------------- ### Bulk Delete with Conditions Source: https://context7.com/w8fyz/architect/llms.txt Performs a bulk delete operation on records that meet specified conditions. Requires at least one condition. ```java // Bulk delete with conditions (requires at least one condition) int deleted = repo.query() .where("active", false) .where("createdAt", Operator.LT, LocalDateTime.now().minusYears(1)) .delete(); ``` -------------------------------- ### IN and NOT IN Queries Source: https://context7.com/w8fyz/architect/llms.txt Constructs queries using IN and NOT IN clauses to filter users based on lists of values for country and ID. ```java // IN and NOT IN queries List selectedUsers = repo.query() .whereIn("country", List.of("USA", "Canada", "Mexico")) .whereNotIn("id", List.of(1L, 2L, 3L)) .findAll(); ``` -------------------------------- ### Extend GenericRepository for Custom User Queries Source: https://context7.com/w8fyz/architect/llms.txt Extend GenericRepository to encapsulate domain-specific query logic for the User entity. This pattern centralizes data access methods. ```java import sh.fyz.architect.repositories.GenericRepository; import sh.fyz.architect.repositories.QueryBuilder.Operator; import sh.fyz.architect.repositories.QueryBuilder.SortOrder; import java.time.LocalDateTime; import java.util.List; import java.util.Map; public class UserRepository extends GenericRepository { public UserRepository() { super(User.class); } public User findByEmail(String email) { return query() .where("email", email) .findFirst(); } public List findActiveByCountry(String country) { return query() .where("country", country) .where("active", true) .orderBy("createdAt", SortOrder.DESC) .findAll(); } public List search(String keyword, int page, int pageSize) { return query() .whereLike("name", "%" + keyword + "%") .orderBy("name", SortOrder.ASC) .limit(pageSize) .offset(page * pageSize) .findAll(); } public List findInactiveOlderThan(int days) { return query() .where("active", false) .where("createdAt", Operator.LT, LocalDateTime.now().minusDays(days)) .findAll(); } public long countByCountry(String country) { return query() .where("country", country) .count(); } public int deactivateInactiveUsers(int daysSinceLastLogin) { return query() .where("lastLoginAt", Operator.LT, LocalDateTime.now().minusDays(daysSinceLastLogin)) .where("active", true) .delete(); } public List findAdmins() { return query() .whereRaw("LOWER(role) = :role", Map.of("role", "admin")) .where("active", true) .orderBy("name") .findAll(); } } ``` ```java // Usage UserRepository users = new UserRepository(); User john = users.findByEmail("john@example.com"); List usUsers = users.findActiveByCountry("USA"); List searchResults = users.search("Smith", 0, 20); long usaCount = users.countByCountry("USA"); ``` -------------------------------- ### Define Custom Cached Repository Source: https://github.com/w8fyz/architect/blob/main/README.md Extend GenericCachedRepository to create a custom repository with cached data access logic. ```java public class UserCachedRepository extends GenericCachedRepository { public UserCachedRepository() { super(User.class); } // same custom methods, backed by Redis cache } ``` -------------------------------- ### QueryBuilder: Terminal Operations for Data Retrieval Source: https://github.com/w8fyz/architect/blob/main/README.md Executes queries to retrieve lists of entities, a single first matching entity, count of matching entities, or to delete matching entities. ```java List users = query().where("active", true).findAll(); User user = query().where("email", "john@example.com").findFirst(); long count = query().where("category", "Books").count(); int deleted = query().where("active", false).delete(); ``` -------------------------------- ### Count Matching Records Source: https://context7.com/w8fyz/architect/llms.txt Calculates the total number of records that match a given set of criteria. ```java // Count matching records long activeCount = repo.query() .where("active", true) .count(); ``` -------------------------------- ### Clear Database with Confirmation Source: https://github.com/w8fyz/architect/blob/main/SKILL.md Clears all tables from the database after requiring a specific confirmation token to prevent accidental data loss. The clearing strategy varies by SQL dialect (e.g., PostgreSQL, MySQL, H2). ```java manager.clearDatabase(MigrationManager.CLEAR_CONFIRMATION); // "CONFIRM_DROP_ALL" ``` -------------------------------- ### Maven Dependency for Architect Source: https://github.com/w8fyz/architect/blob/main/SKILL.md Add this dependency to your Maven project's pom.xml to integrate the Architect library. ```xml sh.fyz Architect 2.2.0 ``` -------------------------------- ### Define a JPA Entity with IdentifiableEntity Source: https://context7.com/w8fyz/architect/llms.txt Implement `IdentifiableEntity` and use JPA annotations to define a `User` entity. Ensure a no-arg constructor is present. The `getId()` method should return the primary key. ```java import sh.fyz.architect.entities.IdentifiableEntity; import jakarta.persistence.*; import java.time.LocalDateTime; @Entity @Table(name = "users") public class User implements IdentifiableEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false, unique = true) private String email; @Column(nullable = false) private String name; @Column(name = "created_at") private LocalDateTime createdAt; private boolean active; private String country; @ManyToOne @JoinColumn(name = "department_id") private Department department; @OneToMany(mappedBy = "user") private List orders; // Required no-arg constructor public User() {} public User(String email, String name) { this.email = email; this.name = name; this.createdAt = LocalDateTime.now(); this.active = true; } @Override public Long getId() { return id; } // Getters and setters... public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isActive() { return active; } public void setActive(boolean active) { this.active = active; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } } ``` -------------------------------- ### QueryBuilder: Null Checks Source: https://github.com/w8fyz/architect/blob/main/README.md Shows how to filter records based on whether a specific field is null or not null. ```java // Null checks query().whereNull("deletedAt") query().whereNotNull("email") ``` -------------------------------- ### Async Terminal Operations in Java Source: https://github.com/w8fyz/architect/blob/main/README.md Perform terminal operations asynchronously using CompletableFuture. These methods return a future that will be completed with the result of the operation. ```java CompletableFuture> users = query().where("active", true).findAllAsync(); CompletableFuture user = query().where("email", "x").findFirstAsync(); CompletableFuture count = query().where("category", "A").countAsync(); CompletableFuture deleted = query().where("active", false).deleteAsync(); ``` -------------------------------- ### Redis Credentials Configuration Source: https://github.com/w8fyz/architect/blob/main/SKILL.md Configures Redis connection details for caching. An optional TTL can be set to apply a default expiry to all cached keys. Keys managed by RedisManager are prefixed with 'architect:'. ```java architect.setRedisCredentials(new RedisCredentials(host, password, port, timeout, maxConnections)); // With a default TTL (seconds) applied to every cached key. 0 = no expiry (default). architect.setRedisCredentials(new RedisCredentials(host, password, port, timeout, maxConnections, 3600)); ``` -------------------------------- ### QueryBuilder: Multiple AND Conditions Source: https://github.com/w8fyz/architect/blob/main/README.md Combines multiple filtering conditions using the AND operator to refine query results. ```java // Multiple conditions (AND) query() .where("category", "Electronics") .where("price", Operator.LT, 100.0) .where("active", true) ``` -------------------------------- ### Stop Architect Application in Java Source: https://github.com/w8fyz/architect/blob/main/README.md Gracefully shut down the Architect application. This ensures all resources like Hibernate sessions and thread pools are properly closed. ```java architect.stop(); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.