UNPKG

@wearesage/schema

Version:

A flexible schema definition and validation system for TypeScript with multi-database support

214 lines (180 loc) โ€ข 6.82 kB
import "reflect-metadata"; import { MetadataRegistry, SchemaBuilder, SchemaReflector } from "../../core"; import { MongoDBAdapter } from "../../adapters/mongodb"; import { Neo4jAdapter } from "../../adapters/neo4j"; import { PostgreSQLAdapter } from "../../adapters/postgresql"; import { Repository } from "../../adapters/repository"; // Import the blog entities import { User } from "../blog/User"; import { Post } from "../blog/Post"; import { Tag } from "../blog/Tag"; // Example using multiple database adapters async function main() { console.log("โšก Multi-Database Example โšก"); // Create a registry and builder const registry = new MetadataRegistry(); const builder = new SchemaBuilder(registry); const reflector = new SchemaReflector(registry); // Register all blog entities console.log("\n๐Ÿ“ Registering blog entities..."); builder.registerEntities([User, Post, Tag]); // Create database adapters with the registry console.log("\n๐Ÿ”Œ Creating database adapters..."); const mongoAdapter = new MongoDBAdapter(registry, "mongodb://localhost:27017/blog"); const neo4jAdapter = new Neo4jAdapter(registry, "bolt://localhost:7687"); const pgAdapter = new PostgreSQLAdapter(registry, "postgres://postgres:password@localhost:5432/blog"); // Create repositories for different entities using different adapters console.log("\n๐Ÿ“š Creating repositories with different adapters..."); const userRepo = new Repository<User>(User, mongoAdapter, registry); const postRepo = new Repository<Post>(Post, neo4jAdapter, registry); const tagRepo = new Repository<Tag>(Tag, pgAdapter, registry); // Example: Create some entities console.log("\n๐Ÿ”ง Creating example entities..."); const user = new User(); user.id = "user1"; user.name = "John Doe"; user.email = "john@example.com"; const post1 = new Post(); post1.id = "post1"; post1.title = "Introduction to Multi-DB Schemas"; post1.content = "This is a post about using multiple databases with TypeScript schemas..."; post1.createdAt = new Date(); post1.author = user; const post2 = new Post(); post2.id = "post2"; post2.title = "Building GraphQL APIs"; post2.content = "GraphQL provides a powerful way to expose your data..."; post2.createdAt = new Date(); post2.author = user; const tag1 = new Tag(); tag1.id = "tag1"; tag1.name = "TypeScript"; const tag2 = new Tag(); tag2.id = "tag2"; tag2.name = "Databases"; // Add tags to posts post1.tags.push(tag1, tag2); post2.tags.push(tag1); // Add posts to user user.posts.push(post1, post2); // Validate entities (optional) console.log("\nโœ… Validating entities..."); const userValidation = reflector.validateEntity(user); console.log(`User valid: ${userValidation.valid}`); if (!userValidation.valid) { console.log("User validation errors:", userValidation.errors); } const post1Validation = reflector.validateEntity(post1); console.log(`Post valid: ${post1Validation.valid}`); if (!post1Validation.valid) { console.log("Post validation errors:", post1Validation.errors); } const tag1Validation = reflector.validateEntity(tag1); console.log(`Tag valid: ${tag1Validation.valid}`); if (!tag1Validation.valid) { console.log("Tag validation errors:", tag1Validation.errors); } // Save entities to their respective databases console.log("\n๐Ÿ’พ Saving entities to their respective databases..."); console.log("Saving user to MongoDB..."); try { await userRepo.save(user); console.log("User saved successfully!"); } catch (error) { console.error("Error saving user:", error); } console.log("\nSaving posts to Neo4j..."); try { await postRepo.save(post1); await postRepo.save(post2); console.log("Posts saved successfully!"); } catch (error) { console.error("Error saving posts:", error); } console.log("\nSaving tags to PostgreSQL..."); try { await tagRepo.save(tag1); await tagRepo.save(tag2); console.log("Tags saved successfully!"); } catch (error) { console.error("Error saving tags:", error); } // Query entities console.log("\n๐Ÿ” Querying entities from different databases..."); console.log("\nQuerying user from MongoDB..."); try { const foundUser = await userRepo.findById("user1"); console.log("Found user:", foundUser ? `${foundUser.name} (${foundUser.email})` : "Not found"); } catch (error) { console.error("Error querying user:", error); } console.log("\nQuerying post from Neo4j..."); try { const foundPost = await postRepo.findById("post1"); console.log("Found post:", foundPost ? `"${foundPost.title}" by ${foundPost.author?.name || 'Unknown'}` : "Not found"); } catch (error) { console.error("Error querying post:", error); } console.log("\nQuerying tag from PostgreSQL..."); try { const foundTag = await tagRepo.findById("tag1"); console.log("Found tag:", foundTag ? foundTag.name : "Not found"); } catch (error) { console.error("Error querying tag:", error); } // Running native queries console.log("\n๐Ÿ”ง Running native queries..."); console.log("\nRunning a native MongoDB query..."); try { const result = await userRepo.runNativeQuery(` { "aggregate": "users", "pipeline": [ { "$match": { "email": "john@example.com" } } ] } `); console.log("MongoDB query result:", result); } catch (error) { console.error("Error running MongoDB query:", error); } console.log("\nRunning a native Cypher query..."); try { const result = await postRepo.runNativeQuery(` MATCH (p:Post)-[:HAS_TAG]->(t:Tag) WHERE t.name = $tagName RETURN p.title, p.content `, { tagName: "TypeScript" }); console.log("Neo4j query result:", result); } catch (error) { console.error("Error running Neo4j query:", error); } console.log("\nRunning a native SQL query..."); try { const result = await tagRepo.runNativeQuery(` SELECT t.name, COUNT(pt.post_id) as post_count FROM tags t LEFT JOIN post_tags pt ON t.id = pt.tag_id GROUP BY t.name `); console.log("PostgreSQL query result:", result); } catch (error) { console.error("Error running PostgreSQL query:", error); } // Clean up connection pools console.log("\n๐Ÿงน Cleaning up connections..."); try { if (typeof (neo4jAdapter as any).close === 'function') { await (neo4jAdapter as any).close(); } if (typeof (pgAdapter as any).close === 'function') { await (pgAdapter as any).close(); } } catch (error) { console.error("Error closing connections:", error); } console.log("\nโœจ Example complete! โœจ"); } // Run the example main().catch(error => { console.error("Error running example:", error); });