Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 7 additions & 1 deletion packages/drivers/sql/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
import { Driver, IntrospectedSchema, IntrospectedTable, IntrospectedColumn, IntrospectedForeignKey } from '@objectql/types';
import knex, { Knex } from 'knex';

/**
* SQL Driver for ObjectQL
* Implements Driver interface from @objectql/types
*/
export class SqlDriver implements Driver {
private knex: Knex;
private config: any;
Expand Down Expand Up @@ -277,7 +281,7 @@ export class SqlDriver implements Driver {
}
}

// Bulk
// Bulk Operations
async createMany(objectName: string, data: any[], options?: any): Promise<any> {
const builder = this.getBuilder(objectName, options);
return await builder.insert(data).returning('*');
Expand Down Expand Up @@ -506,6 +510,8 @@ export class SqlDriver implements Driver {
return data;
}

/**

/**
* Introspect the database schema to discover existing tables, columns, and relationships.
*/
Expand Down
206 changes: 175 additions & 31 deletions packages/foundation/core/RUNTIME_INTEGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ This document explains the integration of `@objectstack/runtime` and `@objectsta

## Overview

As of version 3.0.1, ObjectQL core integrates with the latest ObjectStack runtime packages:
As of version 3.0.1, ObjectQL core natively uses the ObjectStack runtime packages:

- **@objectstack/spec@0.1.2**: Protocol specification with TypeScript interfaces
- **@objectstack/objectql@0.1.1**: Core ObjectQL engine with basic driver management
- **@objectstack/spec@0.1.2**: Protocol specification with standard `DriverInterface`
- **@objectstack/objectql@0.1.1**: Core ObjectQL engine with driver management
- **@objectstack/runtime@0.1.1**: Runtime kernel with application lifecycle orchestration

## Architecture
Expand All @@ -16,17 +16,42 @@ As of version 3.0.1, ObjectQL core integrates with the latest ObjectStack runtim

```
@objectql/core (this package)
├── Extends/complements @objectstack/objectql
├── Uses types from @objectstack/spec
├── Uses @objectstack/objectql for driver management
├── Natively uses @objectstack/spec.DriverInterface (no wrapper)
└── Re-exports types from @objectstack/runtime
```

### Driver Management Integration

**Breaking Change (v3.0.1):** The core package now **natively uses** `DriverInterface` from `@objectstack/spec`:

```typescript
import { ObjectQL } from '@objectql/core';
import type { DriverInterface } from '@objectstack/spec';

// Drivers must implement DriverInterface from @objectstack/spec
const app = new ObjectQL({
datasources: {
default: myDriver // Must be DriverInterface
}
});

await app.init();
```

### Type Exports

The core package exports types from the runtime packages for API compatibility:
The core package exports types from the ObjectStack packages:

```typescript
// Type-only exports to avoid runtime issues
// Driver development types
export type {
DriverInterface,
DriverOptions,
QueryAST
} from '@objectstack/spec';

// Runtime integration types
export type {
ObjectStackKernel,
ObjectStackRuntimeProtocol
Expand All @@ -51,27 +76,151 @@ The current `ObjectQL` class in this package is a **production-ready, feature-ri
- Repository pattern
- Formula engine
- AI integration
- **Native driver management via @objectstack/objectql**

The `ObjectQLEngine` from `@objectstack/objectql` is a **simpler, lightweight** implementation suitable for:

- Basic CRUD operations
- Simple driver management
- Minimal runtime overhead

### Why Type-Only Exports?
### Driver Management (No Compatibility Layer)

ObjectQL now directly uses drivers conforming to `@objectstack/spec.DriverInterface`:

```typescript
// In @objectql/core
import { DriverInterface } from '@objectstack/spec';

private datasources: Record<string, DriverInterface> = {};
private stackEngine: ObjectStackEngine;

constructor(config: ObjectQLConfig) {
this.stackEngine = new ObjectStackEngine({});

// Register drivers directly (no wrapping)
for (const [name, driver] of Object.entries(config.datasources)) {
this.stackEngine.registerDriver(driver, name === 'default');
}
}
```

### Simplified Lifecycle

The ObjectStack engine handles all driver lifecycle management:

```typescript
async close() {
// ObjectStack engine manages all driver disconnect logic
await this.stackEngine.destroy();
}
```

### Custom Driver Development

To build custom drivers for ObjectStack, implement `DriverInterface` from `@objectstack/spec`:

```typescript
import { DriverInterface, QueryAST } from '@objectstack/spec';

export class MyCustomDriver implements DriverInterface {
name = 'MyDriver';
version = '1.0.0';

async connect() {
// Initialize connection
}

async disconnect() {
// Close connection
}

async find(object: string, query: QueryAST, options?: any) {
// Query implementation
return [];
}

async create(object: string, data: any, options?: any) {
// Create implementation
return data;
}

async update(object: string, id: string, data: any, options?: any) {
// Update implementation
return data;
}

async delete(object: string, id: string, options?: any) {
// Delete implementation
}
}
```

Register with ObjectQL:

```typescript
import { ObjectQL } from '@objectql/core';
import { MyCustomDriver } from './my-driver';

const app = new ObjectQL({
datasources: {
default: new MyCustomDriver()
}
});

// Or register dynamically
app.registerDriver('mydb', new MyCustomDriver(), false);
```

## Breaking Changes

### v3.0.1: Native DriverInterface Adoption

The `@objectstack/objectql` package currently has a configuration issue where it points to source files instead of compiled dist files. To avoid runtime errors, we use **type-only imports** which provide TypeScript type checking without executing the runtime code.
**What Changed:**
- `ObjectQLConfig.datasources` now requires `Record<string, DriverInterface>` (from `@objectstack/spec`)
- Removed compatibility wrapper for old `Driver` type
- `app.registerDriver()` now accepts `DriverInterface` instead of legacy `Driver`
- `app.datasource()` now returns `DriverInterface`
- Driver lifecycle is fully managed by ObjectStack engine

**Migration Guide:**

Old code (deprecated):
```typescript
import { Driver } from '@objectql/types';

class MyDriver implements Driver {
// Old Driver interface
}
```

New code (required):
```typescript
import { DriverInterface, QueryAST } from '@objectstack/spec';

class MyDriver implements DriverInterface {
name = 'MyDriver';
version = '1.0.0';

async connect() { }
async disconnect() { }
async find(object: string, query: QueryAST, options?: any) { }
async create(object: string, data: any, options?: any) { }
async update(object: string, id: string, data: any, options?: any) { }
async delete(object: string, id: string, options?: any) { }
}
```

## Usage

### Using the Full-Featured ObjectQL (Recommended)

```typescript
import { ObjectQL } from '@objectql/core';
import { MemoryDriver } from '@objectql/driver-memory';

const app = new ObjectQL({
registry: new MetadataRegistry(),
datasources: { default: driver }
datasources: { default: new MemoryDriver() }
});

await app.init();
Expand All @@ -80,42 +229,37 @@ const repo = ctx.object('todo');
const items = await repo.find({});
```

### Using Type Definitions from Runtime
### Using Type Definitions

```typescript
import type { ObjectStackKernel, SchemaRegistry } from '@objectql/core';
import type { DriverInterface, QueryAST } from '@objectql/core';

// Use types for compile-time checking
function processKernel(kernel: ObjectStackKernel) {
// Your code here
// Use types for compile-time checking (type-only import)
function validateQuery(query: QueryAST): boolean {
return query.object !== undefined;
}
```

## Migration Path

If you want to use the simpler `@objectstack/objectql` implementation:

1. Install it directly: `npm install @objectstack/objectql`
2. Import from the package: `import { ObjectQL } from '@objectstack/objectql'`
3. Note: Ensure the package is properly built before use

## Compatibility

- **@objectstack/spec@0.1.2**: Introduces `searchable` field requirement on FieldConfig
- **Backward Compatible**: All existing ObjectQL APIs remain unchanged
- **Tests**: 236 tests pass successfully, confirming backward compatibility
- **@objectstack/spec@0.1.2**: Standard `DriverInterface` protocol
- **@objectstack/objectql@0.1.1**: Provides driver registration and lifecycle management
- **Breaking Change**: Old `Driver` type from `@objectql/types` is no longer supported
- **Tests**: All tests updated to use `DriverInterface`

## Future Plans

Once the `@objectstack/objectql` package configuration is fixed, we may:
The native integration with `@objectstack/objectql` enables:

1. Use it as a base class for our ObjectQL implementation
2. Move framework-specific features to plugins
3. Provide both lightweight and full-featured options
1. Standardized driver interface across the ObjectStack ecosystem
2. Plugin system for extending driver capabilities
3. Unified driver management across multiple packages
4. Driver marketplace and discovery

## Related Documentation

- [ObjectQL Types](../types/README.md)
- [ObjectQL Platform Node](../platform-node/README.md)
- [@objectstack/spec on npm](https://www.npmjs.com/package/@objectstack/spec)
- [@objectstack/runtime on npm](https://www.npmjs.com/package/@objectstack/runtime)
- [@objectstack/objectql on npm](https://www.npmjs.com/package/@objectstack/objectql)
Loading