Skip to content
Merged
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
11 changes: 11 additions & 0 deletions examples/drivers/fs-demo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Data directory (generated at runtime)
data/

# Node modules
node_modules/

# Build output
dist/

# OS files
.DS_Store
71 changes: 71 additions & 0 deletions examples/drivers/fs-demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# FileSystem Driver Demo

This example demonstrates how to use the `@objectql/driver-fs` package for file-based storage with ObjectQL.

## Features Demonstrated

- ✅ File system-based persistent storage
- ✅ One JSON file per object type
- ✅ CRUD operations (Create, Read, Update, Delete)
- ✅ Query operations (filters, sorting, pagination)
- ✅ Aggregate operations (count, distinct)
- ✅ Human-readable JSON format
- ✅ Automatic backup files

## Running the Demo

```bash
# From the project root
npm run dev

# Or directly
ts-node src/index.ts
```

## What It Does

1. **Initializes** the FileSystem driver with a data directory
2. **Creates** a schema for "projects" with various fields
3. **Inserts** 4 sample projects
4. **Queries** the data with different filters
5. **Updates** a project status
6. **Shows** aggregate operations

## Output

After running, you'll see:
- Console output showing all operations
- A `data/` directory with `projects.json` file
- A `projects.json.bak` backup file

## Inspecting the Data

The data is stored in human-readable JSON:

```bash
cat data/projects.json
```

You can manually edit this file and the changes will be reflected in the application!

## Data Directory Structure

```
fs-demo/
├── src/
│ └── index.ts
├── data/ ← Created on first run
│ ├── projects.json ← Current data
│ └── projects.json.bak ← Backup
├── package.json
└── tsconfig.json
```

## Use Cases

This driver is ideal for:
- Development and prototyping
- Small applications (< 10k records)
- Configuration storage
- Embedded applications
- Scenarios without database setup
19 changes: 19 additions & 0 deletions examples/drivers/fs-demo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "fs-demo",
"version": "0.1.0",
"private": true,
"description": "Example demonstrating @objectql/driver-fs",
"scripts": {
"start": "ts-node src/index.ts",
"dev": "ts-node src/index.ts"
},
"dependencies": {
"@objectql/core": "workspace:*",
"@objectql/driver-fs": "workspace:*"
},
"devDependencies": {
"@types/node": "^20.0.0",
"ts-node": "^10.9.0",
"typescript": "^5.0.0"
}
}
178 changes: 178 additions & 0 deletions examples/drivers/fs-demo/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import { ObjectQL } from '@objectql/core';
import { FileSystemDriver } from '@objectql/driver-fs';
import * as path from 'path';

async function main() {
console.log("🚀 ObjectQL FileSystem Driver Demo\n");

// 1. Initialize Driver with data directory
const dataDir = path.join(__dirname, '../data');
const driver = new FileSystemDriver({
dataDir: dataDir,
prettyPrint: true,
enableBackup: true
});

console.log(`📁 Data directory: ${dataDir}\n`);

// 2. Initialize ObjectQL
const app = new ObjectQL({
datasources: {
default: driver
}
});

// 3. Define Object Schema
app.registerObject({
name: 'projects',
label: 'Projects',
fields: {
name: {
type: 'text',
required: true,
label: 'Project Name'
},
status: {
type: 'select',
options: [
{ label: 'Planning', value: 'planning' },
{ label: 'In Progress', value: 'in_progress' },
{ label: 'Completed', value: 'completed' }
],
defaultValue: 'planning',
label: 'Status'
},
priority: {
type: 'select',
options: [
{ label: 'Low', value: 'low' },
{ label: 'Medium', value: 'medium' },
{ label: 'High', value: 'high' }
],
defaultValue: 'medium',
label: 'Priority'
},
budget: {
type: 'currency',
label: 'Budget'
},
startDate: {
type: 'date',
label: 'Start Date'
}
}
});

await app.init();

// 4. Get Repository
const ctx = app.createContext({ isSystem: true });
const projects = ctx.object('projects');

// 5. Create Sample Projects
console.log("📝 Creating sample projects...\n");

await projects.create({
id: 'PROJ-001',
name: 'Website Redesign',
status: 'in_progress',
priority: 'high',
budget: 50000,
startDate: '2024-01-15'
});

await projects.create({
id: 'PROJ-002',
name: 'Mobile App Development',
status: 'planning',
priority: 'high',
budget: 80000,
startDate: '2024-02-01'
});

await projects.create({
id: 'PROJ-003',
name: 'Infrastructure Upgrade',
status: 'in_progress',
priority: 'medium',
budget: 30000,
startDate: '2024-01-10'
});

await projects.create({
id: 'PROJ-004',
name: 'Marketing Campaign',
status: 'completed',
priority: 'low',
budget: 15000,
startDate: '2023-12-01'
});

console.log("✅ Created 4 projects\n");

// 6. Query Examples
console.log("🔍 Query Examples:\n");

// Find all projects
const allProjects = await projects.find({});
console.log(`📊 Total projects: ${allProjects.length}`);

// Find high priority projects
const highPriority = await projects.find({
filters: [['priority', '=', 'high']]
});
console.log(`🔥 High priority projects: ${highPriority.length}`);
highPriority.forEach(p => console.log(` - ${p.name}`));

// Find in-progress projects
const inProgress = await projects.find({
filters: [['status', '=', 'in_progress']]
});
console.log(`\n⚡ In-progress projects: ${inProgress.length}`);
inProgress.forEach(p => console.log(` - ${p.name}`));

// Find projects with budget > 40000
const largeBudget = await projects.find({
filters: [['budget', '>', 40000]]
});
console.log(`\n💰 Projects with budget > $40,000: ${largeBudget.length}`);
largeBudget.forEach(p => console.log(` - ${p.name}: $${p.budget.toLocaleString()}`));

// Sort by budget
const sortedByBudget = await projects.find({
sort: [['budget', 'desc']]
});
console.log(`\n📈 Projects sorted by budget (desc):`);
sortedByBudget.forEach(p => console.log(` - ${p.name}: $${p.budget.toLocaleString()}`));

// 7. Update Example
console.log(`\n🔄 Updating project status...\n`);
await projects.update('PROJ-002', { status: 'in_progress' });
const updated = await projects.findOne('PROJ-002');
console.log(`✅ Updated ${updated.name} to ${updated.status}`);

// 8. Aggregate Operations
console.log(`\n📊 Aggregate Operations:\n`);

const statusCount = await projects.count({
filters: [['status', '=', 'in_progress']]
});
console.log(`In-progress projects: ${statusCount}`);

const priorities = await projects.distinct('priority');
console.log(`Distinct priorities: ${priorities.join(', ')}`);

// 9. Show file location
console.log(`\n📁 Data Files:\n`);
console.log(` JSON file: ${dataDir}/projects.json`);
console.log(` Backup: ${dataDir}/projects.json.bak`);
console.log(`\n💡 Tip: Open the JSON files to see human-readable data!`);

// Cleanup
await app.close();
}

// Run the demo
if (require.main === module) {
main().catch(console.error);
}
7 changes: 7 additions & 0 deletions examples/drivers/fs-demo/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist"
},
"include": ["src/**/*"]
}
38 changes: 38 additions & 0 deletions packages/drivers/fs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Changelog

All notable changes to the @objectql/driver-fs package will be documented in this file.

## [0.1.1] - 2024-01-16

### Added
- `initialData` configuration option to pre-populate data on initialization
- `clear(objectName)` method to clear all data for a specific object
- `clearAll()` method to clear all data from all objects
- `invalidateCache(objectName)` method to force cache reload
- `getCacheSize()` method to get the number of cached objects
- Chinese documentation (README.zh-CN.md)
- Better error handling for invalid JSON files
- Support for empty JSON files

### Improved
- Enhanced JSON parse error messages with more detailed information
- Better documentation with examples for all new features
- Added 7 new test cases (total: 36 tests)
- TypeScript configuration for proper workspace resolution

## [0.1.0] - 2024-01-16

### Added
- Initial release of FileSystem Driver for ObjectQL
- One JSON file per table/object type
- Atomic write operations with temp file + rename strategy
- Automatic backup files (`.bak`) on write
- Full query support (filters, sorting, pagination, field projection)
- Support for all standard Driver interface methods:
- find, findOne, create, update, delete
- count, distinct
- createMany, updateMany, deleteMany
- Pretty-printed JSON for human readability
- Zero external dependencies (only @objectql/types)
- Comprehensive test suite with 30+ test cases
- Complete documentation and examples
Loading
Loading