sql-ddl-to-json-schema 0.2.1

Parse MySQL and MariaDB DDL into a compact table model and JSON Schema draft-07 documents
Documentation

sql-ddl-to-json-schema

Parse MySQL and MariaDB DDL into a compact table model and JSON Schema draft-07 documents.

Feed one or more SQL Data Definition statements into a Parser, then read one of three outputs:

  • the parse tree, via parse
  • the compact table model, via parse_compact
  • JSON Schema draft-07 documents, one per table, via parse_json_schema

Each of these drains the buffered statements. To reformat a tree you already hold, use the free functions compact_from_tree and json_schema_from_tables.

Statements replay against an in-memory database, so ALTER TABLE, CREATE INDEX, DROP TABLE, RENAME TABLE, and CREATE TABLE ... LIKE all mutate the accumulated tables.

Only DDL is supported. SET parses but is ignored. Database statements (USE, CREATE DATABASE, ALTER DATABASE, DROP DATABASE) parse but produce no tables.

Install

[dependencies]
sql-ddl-to-json-schema = "0.1"

Usage

use sql_ddl_to_json_schema::Parser;

let ddl = "CREATE TABLE users (id INT NOT NULL AUTO_INCREMENT, \
           nickname VARCHAR(255) NOT NULL, PRIMARY KEY (id)) \
           ENGINE MyISAM COMMENT 'All system users'; \
           ALTER TABLE users ADD UNIQUE KEY unq_nick (nickname);";

let mut parser = Parser::new("mysql").unwrap();
parser.feed(ddl);

let tables = parser.parse_compact().unwrap();
assert_eq!(tables[0]["name"], "users");

JSON Schema output:

use sql_ddl_to_json_schema::{JsonSchemaOptions, Parser};

let mut parser = Parser::new("mysql").unwrap();
parser.feed("CREATE TABLE t (id INT PRIMARY KEY, name VARCHAR(30));");

// Default keeps column schemas under `definitions` with `$ref`.
let with_ref = parser.parse_json_schema(JsonSchemaOptions::default()).unwrap();

// Flatten column schemas into `properties`.
let mut parser = Parser::new("mysql").unwrap();
parser.feed("CREATE TABLE t (id INT PRIMARY KEY, name VARCHAR(30));");
let flattened = parser
    .parse_json_schema(JsonSchemaOptions { use_ref: false })
    .unwrap();

Streaming

Input can arrive in chunks. Statements split at unquoted, unescaped semicolons. Cross-chunk state tracks the current quote and escape.

use sql_ddl_to_json_schema::Parser;

let mut parser = Parser::new("mysql").unwrap();
parser.feed("CREATE TABLE ");
parser.feed("t (id INT);");
let tables = parser.parse_compact().unwrap();
assert_eq!(tables[0]["name"], "t");

Dialects

Parser::new accepts "mysql", "mariadb", or an empty string, all of which use the same grammar. Any other value returns Error::UnsupportedDialect.

Datatype mapping

Integer types map to integer with minimum and maximum from the MySQL ranges. bigint uses the JavaScript safe-integer range (+/- 9007199254740991). decimal and float compute maximum from the digit and decimal counts. date, time, and datetime map to the draft-07 format values. enum maps to enum, set to a pattern, uuid to a pattern, and year to a digit-count pattern.

Output types

Every output is a serde_json::Value. The compact model and JSON Schema documents build keys in a fixed order that reads the same as the model builds them.

License

MIT