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
20 changes: 20 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: CI - Build & Test

on:
pull_request:
branches: [ main ]

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Docker Buildx (for multi-platform builds if needed)
uses: docker/setup-buildx-action@v3

- name: Build and test with Makefile
run: |
make test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.src.rock
15 changes: 15 additions & 0 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM openresty/openresty:alpine-fat AS builder

RUN apk add --no-cache \
sqlite

RUN luarocks install busted && \
luarocks install lsqlite3complete

WORKDIR /app

COPY . /app

ENV LUA_PATH="/app/src/?.lua;/app/src/?/init.lua;/usr/local/openresty/lualib/?.lua;;"

CMD ["busted", "spec"]
137 changes: 135 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,135 @@
# lua-lumo
Lua ORM for sqlite3
# Lumo ORM

Lumo ORM is a lightweight, Active Record-style ORM for Lua, designed to work with SQLite.
It provides an intuitive API for database interactions, including querying, relationships, and migrations.

## Features
- Active Record-style models
- Query Builder with chainable methods
- One-to-One, One-to-Many, and Many-to-Many relationships
- Migrations system with CLI support
- LuaRocks-compatible installation
- SQLite support via `lsqlite3complete`

## Installation

You can install Lumo ORM via LuaRocks:

```sh
luarocks install lua-lumo-orm
```

Or clone the repository manually:

```sh
git clone https://github.com/bhhaskin/lua-lumo-orm.git
cd lua-lumo-orm
luarocks make
```

## Usage

### Connecting to a Database

```lua
local Lumo = require("lumo")
Lumo.connect("database.sqlite")
```

### Defining a Model

```lua
local Model = require("lumo.model")

local User = setmetatable({}, Model)
User.__index = User
User.table = "users"

return User
```

### Querying Data

```lua
local User = require("models.user")

-- Fetch all users
local users = User:all()

-- Find a user by ID
local user = User:find(1)
```

### Creating a Record

```lua
local newUser = User:create({ name = "Alice", email = "alice@example.com" })
print("Created user:", newUser.id)
```

### Updating a Record

```lua
user:update({ name = "Alice Wonderland" })
```

### Deleting a Record

```lua
user:delete()
```

### Running Migrations

To apply migrations:
```sh
lua bin/migrate.lua up
```

To rollback:
```sh
lua bin/migrate.lua down
```

## Running Tests

Lumo ORM includes a test suite using `busted`. You can run tests manually with:

```sh
docker build -f Dockerfile.dev -t lumo-orm-test .
docker run --rm lumo-orm-test
```

### Using Makefile for Automation

Instead of manually building and running the Docker container, you can use the provided `Makefile` for convenience.

#### **Build the Docker Image**
```sh
make build
```
This will build the Docker image using `Dockerfile.dev`.

#### **Run Tests**
```sh
make test
```
This will build the image (if not already built) and run the test suite inside a temporary container.

#### **Open a Shell in the Container**
```sh
make shell
```
This will open an interactive shell inside the Docker container for debugging.

#### **Clean Up Docker Images**
```sh
make clean
```
Removes the built Docker image to free up space.

## Contributing
Pull requests are welcome! Please follow the project structure and ensure tests pass before submitting.

## License
This project is licensed under the MIT License.
20 changes: 20 additions & 0 deletions bin/migrate.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
local Lumo = require("lumo")
Lumo.connect("database.sqlite")

local Migrations = require("lumo.migrations")

-- Load migration files
local migrations = {
-- require("lumo.migrations.user_migration"), -- Add more here
}

-- CLI
local action = arg[1]

if action == "up" then
Migrations:migrateUp(migrations)
elseif action == "down" then
Migrations:migrateDown(migrations)
else
print("Usage: lua migrate.lua up | down")
end
8 changes: 8 additions & 0 deletions bin/seed.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
local Lumo = require("lumo")
Lumo.connect("database.sqlite")

local Seeder = require("lumo.seeder")

print("Running database seeder...")
Seeder:run()
print("Seeding finished.")
29 changes: 29 additions & 0 deletions docs/examples/db.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
-- Example usage of lumo.db

local DB = require("lumo.db")

-- Connect to a SQLite database
local db = DB.connect("example.sqlite")

-- Create a table
local create_table_sql = [[
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL
);
]]
db:execute(create_table_sql)

-- Insert a record
local insert_sql = "INSERT INTO users (name, email) VALUES (?, ?);"
db:execute(insert_sql, "Alice", "alice@example.com")

-- Query records
local results = db:query("SELECT * FROM users;")
for _, user in ipairs(results) do
print("User:", user.id, user.name, user.email)
end

-- Close the database connection
db:close()
49 changes: 49 additions & 0 deletions docs/examples/lumo.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
-- Example usage of Lumo ORM

local Lumo = require("lumo")

-- Connect to a SQLite database
Lumo.connect("example.sqlite")

-- Define a User model
local User = setmetatable({}, Lumo.Model)
User.__index = User
User.table = "users"

-- Create a users table
local create_table_sql = [[
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL
);
]]
Lumo.db:execute(create_table_sql)

-- Insert a user
local user = User:create({ name = "Alice", email = "alice@example.com" })
print("Inserted User:", user.id, user.name, user.email)

-- Find a user by ID
local found_user = User:find(user.id)
if found_user then
print("User Found:", found_user.id, found_user.name, found_user.email)
end

-- Update a user
local success = found_user:update({ name = "Alice Updated" })
print("Update Successful:", success)

-- Retrieve all users
local users = User:all()
print("All Users:")
for _, u in ipairs(users) do
print(u.id, u.name, u.email)
end

-- Delete a user
local deleted = found_user:delete()
print("Delete Successful:", deleted)

-- Close the database connection
Lumo.db:close()
38 changes: 38 additions & 0 deletions docs/examples/migrations.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
-- Example usage of lumo.migrations

local DB = require("lumo.db")
local Migrations = require("lumo.migrations")

-- Connect to a SQLite database
local db = DB.connect("example.sqlite")
Migrations.setDB(db)

-- Define a migration
local migration_name = "create_users_table"
local up_sql = [[
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL
);
]]
local down_sql = "DROP TABLE users;"

-- Apply the migration
local applied = Migrations:apply(migration_name, up_sql)
if applied then
print("Migration applied:", migration_name)
else
print("Migration already applied:", migration_name)
end

-- Rollback the migration
local rolled_back = Migrations:rollback(migration_name, down_sql)
if rolled_back then
print("Migration rolled back:", migration_name)
else
print("Migration not found:", migration_name)
end

-- Close the database connection
db:close()
44 changes: 44 additions & 0 deletions docs/examples/model.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
-- Example usage of lumo.model

local DB = require("lumo.db")
local Model = require("lumo.model")

-- Connect to a SQLite database
local db = DB.connect("example.sqlite")
Model.setDB(db)

-- Define a User model
local User = setmetatable({}, Model)
User.__index = User
User.table = "users"

-- Create a users table
local create_table_sql = [[
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL
);
]]
db:execute(create_table_sql)

-- Insert a user
local user = User:create({ name = "Alice", email = "alice@example.com" })
print("Inserted User:", user.id, user.name, user.email)

-- Find a user by ID
local found_user = User:find(user.id)
if found_user then
print("User Found:", found_user.id, found_user.name, found_user.email)
end

-- Update a user
local success = found_user:update({ name = "Alice Updated" })
print("Update Successful:", success)

-- Delete a user
local deleted = found_user:delete()
print("Delete Successful:", deleted)

-- Close the database connection
db:close()
Loading