log.moon

CORM

C

ORM

SQL

Library


Links

  • Github (Source Code)


  • Project Description

    CORM is a very lightweight SQL "ORM" built entirely in C with no external dependencies.

    Why

    We had a class about Backend development in java and in that class we had talked about Hirenate, I was already familiar with ORMs and have used ones before, but sitting in class and having somebody dive a little deep into how this Hibernate worked and how you interface with it gave me the idea to also dig a little deeper and try to actually implement an ORM of my own. Also to piss off the java devs.

    The Macro System

    ORMs ususally rely on a sort of reflection that's built into the language they're implemented in, but as we all know, C has no reflection, and the solution is and always will be macros!.

    It's been a priority for me in corm to keep the API as clean as possible for all users without any unnecessary fluff while at the same time not stealing control from users. It was quite the difficult line to walk, but I'd say I managed to deliver on both accounts, even if a little.

    Here's how you'd define a model:

    typedef struct {
        int id;
        char* username;
        char* email;
        int age;
        bool is_active;
    } User;
    
    DEFINE_MODEL(User, User,
        F_INT(User, id, PRIMARY_KEY | AUTO_INC),
        F_STRING_LEN(User, username, 50, NOT_NULL | UNIQUE),
        F_STRING(User, email, NOT_NULL),
        F_INT(User, age),
        F_BOOL(User, is_active)
    );
    

    DEFINE_MODEL builds a static struct that holds each field's name, type, size, flags, and validator function pointer (if you want to supply one), the field macro are variadic.
    The actual memory layout is figured out using offsetof, which is how CORM knows where each field sits inside your struct.

    Development

    At first it was just curiousity, I just wanted to see if this were even possible, and I just focused on that, I used sqlite as the sql driver and went to work.

    Once I had it working, I looked at how I could improve it and actually make it something akin to a library that can be used by other people.

    The answer was to abstract the backend, and do a bunch of cleaning up and a lot of back and forth on the API, and the mechanisms of when and how to call the driver. Querying also went through a few iterations, I tried my best to make it "secure" and not prone to those pesky code injections, but then I gave up lol. I might revist it another day.

    Other fun stuff like validators, and hooks were also added at a later stage.

    Shortcomings

    There are no shortcomings, it's perfect.

    Spoiler

    why is he lying