# JSON Writer

Generates database schema definitions in JSON format.

## Overview

The JSON Writer converts RelSpec's internal database model representation into JSON format, providing a complete, structured representation of the database schema.

## Features

- Generates RelSpec's canonical JSON schema format
- Complete schema representation including:
  - Databases and schemas
  - Tables, columns, and data types
  - Constraints (PK, FK, unique, check)
  - Indexes
  - Relationships
  - Views and sequences
- Pretty-printed, human-readable output
- Suitable for version control
- Ideal interchange format

## Usage

### Basic Example

```go
package main

import (
    "git.warky.dev/wdevs/relspecgo/pkg/models"
    "git.warky.dev/wdevs/relspecgo/pkg/writers"
    "git.warky.dev/wdevs/relspecgo/pkg/writers/json"
)

func main() {
    options := &writers.WriterOptions{
        OutputPath: "schema.json",
    }

    writer := json.NewWriter(options)
    err := writer.WriteDatabase(db)
    if err != nil {
        panic(err)
    }
}
```

### CLI Examples

```bash
# Export PostgreSQL database to JSON
relspec --input pgsql \
  --conn "postgres://localhost/mydb" \
  --output json \
  --out-file schema.json

# Convert GORM models to JSON
relspec --input gorm --in-file models.go --output json --out-file schema.json

# Convert DBML to JSON
relspec --input dbml --in-file diagram.dbml --output json --out-file schema.json
```

## Generated JSON Example

```json
{
  "name": "myapp",
  "description": "",
  "database_type": "postgresql",
  "database_version": "",
  "source_format": "pgsql",
  "schemas": [
    {
      "name": "public",
      "description": "",
      "tables": [
        {
          "name": "users",
          "schema": "public",
          "description": "",
          "columns": {
            "id": {
              "name": "id",
              "table": "users",
              "schema": "public",
              "type": "bigint",
              "length": 0,
              "precision": 0,
              "scale": 0,
              "not_null": true,
              "is_primary_key": true,
              "auto_increment": true,
              "default": "",
              "sequence": 1
            },
            "username": {
              "name": "username",
              "table": "users",
              "schema": "public",
              "type": "varchar",
              "length": 50,
              "not_null": true,
              "is_primary_key": false,
              "auto_increment": false,
              "sequence": 2
            },
            "email": {
              "name": "email",
              "table": "users",
              "schema": "public",
              "type": "varchar",
              "length": 100,
              "not_null": true,
              "sequence": 3
            }
          },
          "constraints": {
            "pk_users": {
              "name": "pk_users",
              "type": "PRIMARY KEY",
              "table": "users",
              "schema": "public",
              "columns": ["id"]
            },
            "uq_users_username": {
              "name": "uq_users_username",
              "type": "UNIQUE",
              "table": "users",
              "schema": "public",
              "columns": ["username"]
            }
          },
          "indexes": {
            "idx_users_email": {
              "name": "idx_users_email",
              "table": "users",
              "schema": "public",
              "columns": ["email"],
              "unique": false,
              "type": "btree"
            }
          },
          "relationships": {}
        },
        {
          "name": "posts",
          "schema": "public",
          "columns": {
            "id": {
              "name": "id",
              "type": "bigint",
              "not_null": true,
              "is_primary_key": true,
              "sequence": 1
            },
            "user_id": {
              "name": "user_id",
              "type": "bigint",
              "not_null": true,
              "sequence": 2
            },
            "title": {
              "name": "title",
              "type": "varchar",
              "length": 200,
              "not_null": true,
              "sequence": 3
            },
            "content": {
              "name": "content",
              "type": "text",
              "not_null": false,
              "sequence": 4
            }
          },
          "constraints": {
            "fk_posts_user_id": {
              "name": "fk_posts_user_id",
              "type": "FOREIGN KEY",
              "table": "posts",
              "schema": "public",
              "columns": ["user_id"],
              "referenced_table": "users",
              "referenced_schema": "public",
              "referenced_columns": ["id"],
              "on_delete": "CASCADE",
              "on_update": "NO ACTION"
            }
          },
          "indexes": {
            "idx_posts_user_id": {
              "name": "idx_posts_user_id",
              "columns": ["user_id"],
              "unique": false,
              "type": "btree"
            }
          }
        }
      ],
      "views": [],
      "sequences": []
    }
  ]
}
```

## Schema Structure

The JSON format includes:

### Database Level
- `name` - Database name
- `description` - Database description
- `database_type` - Database system type
- `database_version` - Version information
- `source_format` - Original source format
- `schemas` - Array of schema objects

### Schema Level
- `name` - Schema name
- `description` - Schema description
- `tables` - Array of table objects
- `views` - Array of view objects
- `sequences` - Array of sequence objects

### Table Level
- `name` - Table name
- `schema` - Schema name
- `description` - Table description
- `columns` - Map of column objects
- `constraints` - Map of constraint objects
- `indexes` - Map of index objects
- `relationships` - Map of relationship objects

### Column Level
- `name` - Column name
- `type` - Data type
- `length` - Type length
- `precision`, `scale` - Numeric precision
- `not_null` - NOT NULL flag
- `is_primary_key` - Primary key flag
- `auto_increment` - Auto-increment flag
- `default` - Default value
- `sequence` - Column order

### Constraint Level
- `name` - Constraint name
- `type` - Constraint type (PRIMARY KEY, FOREIGN KEY, UNIQUE, CHECK)
- `columns` - Constrained columns
- `referenced_table`, `referenced_schema` - FK references
- `referenced_columns` - Referenced columns
- `on_delete`, `on_update` - FK actions

### Index Level
- `name` - Index name
- `columns` - Indexed columns
- `unique` - Unique flag
- `type` - Index type

## Use Cases

- **Version Control** - Track schema changes in git
- **Documentation** - Human-readable schema documentation
- **Interchange** - Standard format for tool integration
- **Backup** - Schema backup without database access
- **Testing** - Test data for schema validation
- **API** - Schema information for APIs

## Notes

- Output is pretty-printed with 2-space indentation
- Preserves all schema metadata
- Can be round-tripped (read and write) without loss
- Schema-agnostic format
- Ideal for automation and tooling
