tren
Version, currently 2.0.011 versions
github.com/sdogruyol/tren
Use SQL as first-class Crystal methods
129 stars
0 dependents
License: MIT
Installation
# Add this to your shard.yml
dependencies:
tren:
github: sdogruyol/tren
version: ~> 2.0.0Then run:
shards installshard.yml
- Crystal
- no constraint declared
- License
- MIT
- Authors
- Fatih Kadir Akın, Serdar Doğruyol
Dependencies
This version declares no dependencies.
README

[](https://github.com/sdogruyol/tren/actions/workflows/ci.yml)
# Tren
Use SQL files as first-class Crystal methods.
Tren reads SQL files at compile time and generates native Crystal methods from them.
You keep SQL in `.sql` files, then call it like regular Crystal code.
## Why Tren?
- Write SQL where it belongs: in SQL files.
- Keep typed method signatures in metadata.
- Get Crystal overload checks at compile time.
- Compose SQL snippets without repeating yourself.
## 30-Second Example
Create `queries/users.sql`:
```sql
-- name: get_users(name : String, age : Int32)
SELECT * FROM users WHERE name = '{{ name }}' AND age = {{ age }}
```
Load and call it:
```crystal
require "tren"
Tren.load("./queries/*.sql")
sql = get_users("john", 42)
# => "SELECT * FROM users WHERE name = 'john' AND age = 42"
```
That method (`get_users`) is generated by Tren during compilation.
## Installation
Add this to your `shard.yml`:
```yaml
dependencies:
tren:
github: sdogruyol/tren
```
Then install dependencies:
```bash
shards install
```
## SQL File Format
Each query must start with metadata:
```sql
-- name: method_name(arg : Type, ...)
```
After that line, write the SQL body:
```sql
-- name: find_user(id : Int32)
SELECT * FROM users WHERE id = {{ id }}
```
## Parameter Rules
- `{{ value }}`: escaped parameter (default, safer).
- `{{! value }}`: raw parameter (not escaped).
```sql
-- name: by_name(name : String)
SELECT * FROM users WHERE name = '{{ name }}'
-- name: with_clause(clause : String)
SELECT * FROM users {{! clause }}
```
## Overloading
Multiple SQL entries can share the same method name with different signatures:
```sql
-- name: get_users(name : String, surname : String)
SELECT * FROM users WHERE name = '{{ name }}' AND surname = '{{ surname }}'
-- name: get_users(name : String, age : Int32)
SELECT * FROM users WHERE name = '{{ name }}' AND age = {{ age }}
```
Crystal resolves overloads and reports errors if arguments do not match.
## Composing Queries
You can reuse generated SQL methods to build larger queries:
```sql
-- name: filter_user(name : String, surname : String)
WHERE name = '{{ name }}' AND surname = '{{ surname }}'
-- name: get_users(name : String, surname : String)
SELECT * FROM users {{! filter_user(name, surname) }}
```
## Escaping Behavior
String parameters are escaped by default.
Non-string values are passed through as-is.
You can customize the escape behavior:
```crystal
Tren.escape_character = "\\"
# => escapes both quotes and backslashes with a backslash prefix (default)
Tren.escape_character = "\\'"
# => PostgreSQL-style single-quote escaping ("I'm" => "I''m")
```
## Security Notes
- Prefer `{{ value }}` over raw interpolation.
- Use `{{! ... }}` only for trusted SQL fragments.
- If your driver supports prepared statements, prefer them for user input.
## Error Messages
Tren now fails with clearer parse errors (including file and line) for invalid metadata or malformed placeholders.
Expected metadata format:
```sql
-- name: method_name(args)
```
## Development
Run tests:
```bash
crystal spec
```
Run format check:
```bash
crystal tool format --check src spec
```
## Contributing
1. Fork it ([github.com/sdogruyol/tren/fork](https://github.com/sdogruyol/tren/fork))
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am "Add some feature"`)
4. Push to the branch (`git push origin my-new-feature`)
5. Open a Pull Request
## Contributors
- [f](https://github.com/f) Fatih Kadir Akın - creator, maintainer
- [sdogruyol](https://github.com/sdogruyol) Serdar Doğruyol - creator, maintainer
_Built on a TREN from Ankara to Istanbul._
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
2.0.0- Tagged
- Mar 9, 2026
- Commit
7c0af9d298e4- Indexed
- yes
Dependents
No indexed shard depends on this one yet.
Repository
github.com/sdogruyol/tren
Metadata
- Created
- Aug 12, 2026
- Updated
- Aug 12, 2026
- Synced
- Aug 12, 2026
- Versions
- 11