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
75 changes: 75 additions & 0 deletions docs/examples/collection.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
local Collection = require("lumo.collection")

-- Sample data
local users = {
{ id = 1, name = "Alice", age = 28 },
{ id = 2, name = "Bob", age = 35 },
{ id = 3, name = "Charlie", age = 24 },
{ id = 4, name = "David", age = 30 }
}

-- Create a collection
local userCollection = Collection:new(users)

print("---- Original Collection ----")
for _, user in ipairs(userCollection:toArray()) do
print(user.id, user.name, user.age)
end

-- Map: Add a new property
local updatedUsers = userCollection:map(function(user)
user.isAdult = user.age >= 18
return user
end)

print("\n---- Users with isAdult field ----")
for _, user in ipairs(updatedUsers:toArray()) do
print(user.id, user.name, user.age, "isAdult:", user.isAdult)
end

-- Filter: Get users older than 25
local filteredUsers = userCollection:filter(function(user)
return user.age > 25
end)

print("\n---- Users older than 25 ----")
for _, user in ipairs(filteredUsers:toArray()) do
print(user.id, user.name, user.age)
end

-- First and Last
print("\nFirst user:", userCollection:first().name)
print("Last user:", userCollection:last().name)

-- Pluck: Extract names
local names = userCollection:pluck("name")
print("\n---- User Names ----")
for _, name in ipairs(names) do
print(name)
end

-- Sorting by age
local sortedUsers = userCollection:sortBy("age")
print("\n---- Users Sorted by Age ----")
for _, user in ipairs(sortedUsers:toArray()) do
print(user.id, user.name, user.age)
end

-- Reverse
local reversedUsers = userCollection:reverse()
print("\n---- Users in Reverse Order ----")
for _, user in ipairs(reversedUsers:toArray()) do
print(user.id, user.name, user.age)
end

-- Reduce: Get total age sum
local totalAge = userCollection:reduce(function(acc, user)
return acc + user.age
end, 0)
print("\nTotal age of all users:", totalAge)

-- Check if collection contains a user older than 30
local hasOlderUser = userCollection:contains(function(user)
return user.age > 30
end)
print("\nContains user older than 30?", hasOlderUser)
80 changes: 51 additions & 29 deletions docs/examples/model.lua
Original file line number Diff line number Diff line change
@@ -1,44 +1,66 @@
-- 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")
-- Connect to an in-memory SQLite database
local db = DB.connect(":memory:")
Model.setDB(db)

-- Create a test table
db:execute([[
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
email TEXT,
age INTEGER
);
]])

-- 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)
-- **Create a new user**
local user = User:create({ name = "Alice", email = "alice@example.com", age = 25 })
print("Created User:", user.id, user.name, user.email, user.age)

-- 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)
-- **Find a user by ID**
local foundUser = User:find(user.id)
if foundUser then
print("Found User:", foundUser.id, foundUser.name, foundUser.email)
end

-- Update a user
local success = found_user:update({ name = "Alice Updated" })
print("Update Successful:", success)
-- **Update a user**
foundUser.email = "alice@newdomain.com"
foundUser:save()
print("Updated Email:", foundUser.email)

-- **Increment age**
foundUser:increment("age", 1)
print("Incremented Age:", foundUser.age)

-- **Retrieve all users as a collection**
local users = User:all()
print("Total Users:", users:count())

-- **Use where queries**
local filteredUsers = User:where("age", ">", 20):get()
print("Users older than 20:", filteredUsers:count())

-- **Find or create a user**
local existingOrNewUser = User:find_or_create({ email = "bob@example.com" }, { name = "Bob", age = 30 })
print("Find or Create User:", existingOrNewUser.id, existingOrNewUser.name)

-- **Update or create a user**
local updatedOrCreatedUser = User:update_or_create({ email = "bob@example.com" }, { age = 35 })
print("Update or Create User:", updatedOrCreatedUser.id, updatedOrCreatedUser.age)

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

-- Close the database connection
db:close()
-- **Verify deletion**
local checkUser = User:find(user.id)
if not checkUser then
print("User successfully deleted.")
end
33 changes: 33 additions & 0 deletions rockspecs/lumo-orm-1.0-0.rockspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package = "lumo-orm"
version = "1.0-0"
source = {
url = "https://github.com/bhhaskin/lua-lumo-orm/archive/refs/tags/v1.0-0.tar.gz",
md5 = "bcadb1b22792463f7d77158a67a2af2f",
dir = "lua-lumo-orm-1.0-0"
}
description = {
summary = "A lightweight Active Record ORM for Lua with SQLite support",
detailed = [[
Lumo-ORM provides an Eloquent-style ORM for Lua, built to work with SQLite.
It includes migrations, a query builder, relationships, and Active Record pattern support.
]],
license = "MIT",
homepage = "https://github.com/bhhaskin/lua-lumo-orm",
maintainer = "Bryan Haskin <bhhaskin@bitsofsimplicity.com>"
}
dependencies = {
"lua >= 5.1",
"lsqlite3complete"
}
build = {
type = "builtin",
modules = {
["lumo"] = "src/lumo.lua",
["lumo.db"] = "src/lumo/db.lua",
["lumo.model"] = "src/lumo/model.lua",
["lumo.query_builder"] = "src/lumo/query_builder.lua",
["lumo.relationships"] = "src/lumo/relationships.lua",
["lumo.migrations"] = "src/lumo/migrations.lua",
["lumo.collection"] = "src/lumo/collection.lua",
}
}
115 changes: 115 additions & 0 deletions spec/collection_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
local Collection = require("lumo.collection")
local busted = require("busted")

describe("Collection", function()

it("should create a collection", function()
local col = Collection:new({1, 2, 3})
assert.are.equal(3, col:count())
end)

it("should map over a collection", function()
local col = Collection:new({1, 2, 3})
local new_col = col:map(function(item) return item * 2 end)

assert.are.same({2, 4, 6}, new_col:toArray())
end)

it("should filter a collection", function()
local col = Collection:new({1, 2, 3, 4, 5})
local filtered = col:filter(function(item) return item % 2 == 0 end)

assert.are.same({2, 4}, filtered:toArray())
end)

it("should get the first item", function()
local col = Collection:new({10, 20, 30})
assert.are.equal(10, col:first())
end)

it("should get the last item", function()
local col = Collection:new({10, 20, 30})
assert.are.equal(30, col:last())
end)

it("should convert to a plain Lua table", function()
local col = Collection:new({10, 20, 30})
assert.are.same({10, 20, 30}, col:toArray())
end)

it("should count the number of items", function()
local col = Collection:new({1, 2, 3, 4})
assert.are.equal(4, col:count())
end)

it("should check if an instance is a Collection", function()
local col = Collection:new({1, 2, 3})
assert.is_true(col:isInstanceOf(Collection))
end)

it("should pluck a field from a collection of tables", function()
local col = Collection:new({
{ id = 1, name = "Alice" },
{ id = 2, name = "Bob" },
{ id = 3, name = "Charlie" }
})

local names = col:pluck("name")
assert.are.same({"Alice", "Bob", "Charlie"}, names:toArray())
end)

it("should iterate over each item", function()
local col = Collection:new({1, 2, 3})
local sum = 0
col:each(function(item) sum = sum + item end)

assert.are.equal(6, sum)
end)

it("should check if collection contains a matching item", function()
local col = Collection:new({1, 2, 3, 4})
assert.is_true(col:contains(function(item) return item == 3 end))
assert.is_false(col:contains(function(item) return item == 10 end))
end)

it("should reduce a collection to a single value", function()
local col = Collection:new({1, 2, 3, 4})
local sum = col:reduce(function(acc, item) return acc + item end, 0)

assert.are.equal(10, sum)
end)

it("should sort a collection by a key", function()
local col = Collection:new({
{ id = 2, name = "Bob" },
{ id = 1, name = "Alice" },
{ id = 3, name = "Charlie" }
})

local sorted = col:sortBy("id")
local sorted_ids = sorted:pluck("id"):toArray()

assert.are.same({1, 2, 3}, sorted_ids)
end)

it("should sort a collection by a key in descending order", function()
local col = Collection:new({
{ id = 2, name = "Bob" },
{ id = 1, name = "Alice" },
{ id = 3, name = "Charlie" }
})

local sorted = col:sortBy("id", false)
local sorted_ids = sorted:pluck("id"):toArray()

assert.are.same({3, 2, 1}, sorted_ids)
end)

it("should reverse the collection", function()
local col = Collection:new({1, 2, 3, 4})
local reversed = col:reverse()

assert.are.same({4, 3, 2, 1}, reversed:toArray())
end)

end)
Loading