- Contributors
- heyhey123, Radiation-pi
- Supported Skript Version
- 2.16
- 2.17
- Supported Minecraft Versions
- 26.1
An ORM for Skript.
Describe a table once, then read and write rows with Skript syntax instead of writing SQL.
skript-orm adds database access to Skript as ordinary Skript elements. A script declares the
connection and the table it wants, and from then on inserts, reads, updates and deletes are sections
and effects with a where block, a values block and named connections —
no SQL, no JDBC, no config file.
Statements run off the server thread and hand their results back as ordinary Skript variables. Nothing
has to be typed twice: the table is described once and every statement uses that description to build
the SQL, bind the parameters and read the row back into a variable shaped like
{_user::name}.
Requirements
- Paper 26.2 or newer — the server line this build compiles against.
- Skript 2.16.2 or newer. On anything older the plugin disables itself and says why in the console.
- MySQL 8 (or a compatible server). The shipped implementation targets MySQL and is tested against MySQL 8; nothing else has to be installed, because Paper already carries the driver.
- SkBee is optional and only needed for nbtcompound columns.
- No commands and no permissions. Everything is a Skript element, so there is nothing to grant and nothing to type into chat.
- No config file and no data folder. Connections and tables are written in scripts, where the rest of the plugin's behaviour is.
Install
- Download skriptorm-<version>.jar from the releases page linked at the bottom.
- Put it in the server's plugins/ folder, next to Skript.
- Restart the server, then write the connection and the table into a script and /sk reload it.
plugin's own package (io.github.heyhey123.skriptorm.libs.*) so they cannot collide with
another plugin's copy. Nothing is obfuscated: the source is public and readable, as the resource
standards require.
A script looks like this
Code:
on load:
create a connection to database "MySQL" with properties:
url: "jdbc:mysql://localhost:3306/mydb"
username: "root"
password: "123456"
register a database table "users":
id: bigint, primary key, auto increment, not null
name: string(64), not null
age: int, nullable
command /whois <text>:
trigger:
select one entity from table "users" and store the result in {_user::*}:
where all:
name = arg-1
if last database error is set:
send "Lookup failed: %last database error%" to sender
stop
send "name: %{_user::name}%, age: %{_user::age}%" to sender
command /adduser <text> <integer>:
trigger:
insert one entity into table "users" and wait:
values:
name: arg-1
age: arg-2
if last database error is set:
send "Insert failed: %last database error%" to console
Features
- As many connections as a script wants. create a connection makes one the default, named "logs" keeps another alongside it, and in connection "logs": or use connection "logs" says which one a statement uses.
- A table is described once. register a database table takes the columns, their types, keys and modifiers; the plugin builds the DDL and remembers the shape for every later statement.
- Everything that touches rows is a Skript element. Writing, reading, updating and deleting are their own syntaxes with their own bodies, and a read always waits for its result.
- A transaction is one section. database transaction: commits when its body ends, rolls back when a statement in it fails, holds one connection for as long as it runs, and can be given a timeout.
- A failure is a value. After an operation written with and wait, last database error holds what went wrong; an operation that worked leaves it unset.
- Typed columns, converted for you. Numbers, text, booleans, UUIDs, dates, timespans, locations, item stacks and NBT compounds are read and written as the Skript values they are.
Everything it adds
Sections — a body, and a colon when written in a script
Code:
Create Database Connection:
create [a] connection named %string% to [database] %string% [with properties]
create [a] connection to [database] %string% [with properties]
Database Transaction:
database transaction [on connection %string%] [with [a] timeout [of] %timespan%]
Delete Entities:
delete [entities] from [table] %string% [with limit %integer%] [and wait]
Delete Entity By ID:
delete [one] [entity] from [table] %string% by id %object% [and wait]
In Database Connection:
in [the] [database] connection %string%
Insert Entity If Absent:
insert [one] [entity] if absent into [table] %string% [and wait]
insert [one] [entity] %objects% if absent into [table] %string% [and wait]
Insert Many Entities:
insert many [entities] into [table] %string% [and wait]
insert many [entities] %objects% into [table] %string% [and wait]
Insert One Entity:
insert one [entity] into [table] %string% [and wait]
insert one [entity] %objects% into [table] %string% [and wait]
Register Database Table:
register [a] [database] table %string%
Select Entity By ID:
select [one] [entity] from [table] %string% by id %object% [and] store [the] [result] in %objects% [and wait]
Select Many Entities:
select many [entities] from [table] %string% [and] store [the] [results] in %objects% [and wait]
Select One Entity:
select one [entity] from [table] %string% [and] store [the] [result] in %objects% [and wait]
Select Page:
select page %integer% [with] size %integer% from [table] %string% [and] store [the] [results] in %objects% [and wait]
Update Entities:
update [entities] in [table] %string% [with limit %integer%] [and wait]
update [entities] %objects% in [table] %string% [with limit %integer%] [and wait]
Update Entity By ID:
update [one] [entity] in [table] %string% by id %object% [and wait]
update [one] [entity] %objects% in [table] %string% by id %object% [and wait]
Upsert Entity By ID:
upsert [one] [entity] in [table] %string% by id %object% [and wait]
upsert [one] [entity] %objects% in [table] %string% by id %object% [and wait]
Effects — the same operations without a colon, for a section that would have no body
Code:
Delete Entities Without A Colon:
delete [entities] from [table] %string% [with limit %integer%] [and wait]
Delete One Entity By ID Without A Colon:
delete [one] [entity] from [table] %string% by id %object% [and wait]
Disconnect Database:
disconnect [from] all [database] connections
disconnect [from] [the] [database] connection %string%
disconnect [from] [the] [current] [database] [connection]
Insert Entity If Absent From A Variable Without A Colon:
insert [one] [entity] %objects% if absent into [table] %string% [and wait]
Insert Many Entities From A Variable Without A Colon:
insert many [entities] %objects% into [table] %string% [and wait]
Insert One Entity From A Variable Without A Colon:
insert one [entity] %objects% into [table] %string% [and wait]
Make Database Connection The Default:
make [the] connection %string% the default [database] [connection]
Rollback Database Transaction:
roll[ ]back [the] [current] [database] transaction
Select Entity By ID Without A Colon:
select [one] [entity] from [table] %string% by id %object% [and] store [the] [result] in %objects% [and wait]
Select Many Entities Without A Filter:
select many [entities] from [table] %string% [and] store [the] [results] in %objects% [and wait]
Select One Entity Without A Filter:
select one [entity] from [table] %string% [and] store [the] [result] in %objects% [and wait]
Select Page Without A Filter:
select page %integer% [with] size %integer% from [table] %string% [and] store [the] [results] in %objects% [and wait]
Update One Entity By ID From A Variable Without A Colon:
update [one] [entity] %objects% in [table] %string% by id %object% [and wait]
Upsert One Entity By ID From A Variable Without A Colon:
upsert [one] [entity] %objects% in [table] %string% by id %object% [and wait]
Use Database Connection:
use [the] [database] connection %string%
Expressions
Code:
Last Database Error:
[the] last (database|query) error
Good to know
- Waiting is explicit. A statement written with and wait runs on the server thread and reports its failure through last database error; without it the statement is queued and any asynchronous failure is only logged.
- Reads always wait, whether or not and wait is written, because the result is needed in the line that follows.
- A failed statement inside a transaction empties the rest of the body and the transaction is rolled back when the body ends, so a half-done group cannot commit.
- NBT columns need SkBee. SkBee is what gives scripts a way to build a compound, so nbtcompound columns are only usable with it installed. Everything else works without it.
- Paper 26.2 / Skript 2.16.2 is the tested combination and the one CI runs on every change, together with the MySQL suites.
Links
- Source code — the repository, with the full documentation in docs/.
- Releases — the jar, its checksum and the changes in each version.
- Transactions and connections — the two pages that explain the parts worth reading twice.
- Contributing — how to build it, run the test server and add an implementation.
- Issues — bug reports and questions.
License
MIT. Use it, change it, ship it in a paid setup, read the source and decompile the jar — the resource
standards require that last one to be allowed, and the license grants it anyway.