Database Schema Code Generation (orionc Enhancement)

Goal

Generate C struct definitions from .orion database schemas, making the schema the single source of truth for both the database implementation and application code.

Status

.orion schema updated with length attributes for strings ✅ Mock generated header created (build/generated/examples/socialfeed/socialfeed.h) ✅ db_simple_xml.h updated to include generated header ✅ All generated code consolidated into single socialfeed.h file ⏳ orionc compiler needs database schema parsing support

Schema Example (socialfeed.orion)

<database name="db" class="SimpleXMLDatabase" source="socialfeed_seed.xml">
  <table name="authors" model="author">
    <field name="id" type="integer" key="YES"/>
    <field name="name" type="string" length="64"/>
    <field name="avatar" type="string" length="256"/>
  </table>
  
  <table name="posts" model="post">
    <field name="id" type="integer" key="YES"/>
    <field name="author_id" type="integer" relation="authors.id"/>
    <field name="title" type="string" length="256"/>
    <field name="body" type="string" length="2048"/>
    <field name="like_count" type="integer"/>
    <field name="comment_count" type="integer"/>
  </table>
</database>

Generated Output (socialfeed.h)

Single generated header contains everything from .orion:

  • Menu/toolbar IDs from <menus> and <toolbars>
  • Form definitions from <forms>
  • Database schema from <database>
// Generated by orionc from socialfeed.orion
#ifndef __SOCIALFEED_GENERATED_H__
#define __SOCIALFEED_GENERATED_H__

// Menu IDs
enum {
  ID_FILE_QUIT = 1000,
  ID_POST_NEW,
  // ...
};

// Table identifiers
enum {
  TABLE_AUTHORS = 0,
  TABLE_POSTS,
  TABLE_COMMENTS,
  TABLE_COUNT
};

// Generated structs (from <database> schema)
typedef struct author_s {
  int32_t id;
  char name[64];
  char avatar[256];
} author_t;

typedef struct post_s {
  int32_t id;
  int32_t author_id;
  char title[256];
  char body[2048];
  int32_t like_count;
  int32_t comment_count;
} post_t;

// Field bindings for DDX (auto-generated from schema)
extern const db_field_msg_binding_t author_bindings[];
extern const db_field_msg_binding_t post_bindings[];
extern const db_api_def_t socialfeed_database_api;

// Form definitions
extern const form_def_t socialfeed_main_window_form;
extern const form_def_t socialfeed_new_post_form;
// ...

#endif // __SOCIALFEED_GENERATED_H__

Type Mapping

.orion type C type Notes
integer int32_t Fixed-size for portability
string with length="N" char[N] Fixed-size buffer
boolean bool From <stdbool.h>
float float Single precision
double double Double precision

Field Attributes

  • name — Field identifier (required)
  • type — Data type (required)
  • length — String buffer size (required for type="string")
  • key="YES" — Primary key marker
  • relation="table.field" — Foreign key relationship

orionc Implementation Tasks

1. Parse <database> Elements

  • Extract database name, class, source path
  • Enumerate <table> children

2. Parse <table> Elements

  • Extract table name, model name
  • Generate TABLE_* enum constants
  • Enumerate <field> children

3. Parse <field> Elements

  • Map XML type to C type
  • Handle length attribute for strings
  • Preserve key and relation as comments

4. Generate Struct Definitions

  • Output typedef struct {name}_s { ... } {name}_t;
  • Use int32_t for integers (fixed-size)
  • Use char[N] for strings with declared length

5. Generate Field Bindings

  • Create db_field_msg_binding_t arrays from schema
  • Map field names to column IDs (COL_* enums)
  • Export as extern const arrays

6. Generate Database API Metadata

  • Create db_api_def_t struct with all tables
  • Include table count, bindings arrays
  • Export for tableview/inspector use

Benefits

Single source of truth — Schema defined once in .orionZero duplication — No manual struct definitions ✅ Type safety — Compiler validates field access ✅ Auto-sync — Database and app share same definitions ✅ IDE support — Autocomplete from generated structs ✅ Consistency — Field bindings generated from same schema

Migration Path

  1. Add length attributes to existing schemas ✅
  2. Create mock generated headers ✅
  3. Update database implementations to include generated headers ✅
  4. Implement orionc database parsing ⏳
  5. Test generated code compiles ⏳
  6. Remove manual struct definitions ⏳

Usage After Generation

// Application code includes the generated header
#include "build/generated/examples/socialfeed/socialfeed.h"

// Structs available automatically:
author_t author = { .name = "Alice", .avatar = "alice.png" };
post_t post = { .title = "Hello", .body = "World" };

// Table IDs from generated enum:
send_db_message(db, dbInsert, TABLE_AUTHORS, &author);

// Field bindings auto-available:
tableview_params_t params = {
  .db = db,
  .table_id = TABLE_POSTS,
  .field_names = (const char *[]){"title", "author", "like_count", NULL},
};
  • examples/socialfeed/socialfeed.orion — Schema definitions
  • build/generated/examples/socialfeed/socialfeed.h — Generated header (menus, forms, database)
  • examples/socialfeed/socialfeed.h — App header (includes generated header)
  • examples/socialfeed/db_simple_xml.h — Database proc header
  • examples/socialfeed/db_simple_xml.c — Database implementation
  • tools/orionc.c — Compiler (needs database parsing)

Orion UI Framework – built on SDL2 and OpenGL 3.2+

This site uses Just the Docs, a documentation theme for Jekyll.