Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/wookay/octo.jl
Octo.jl 🐙 is an SQL Query DSL in Julia
https://github.com/wookay/octo.jl
dsl julia query repo sql
Last synced: 1 day ago
JSON representation
Octo.jl 🐙 is an SQL Query DSL in Julia
- Host: GitHub
- URL: https://github.com/wookay/octo.jl
- Owner: wookay
- License: other
- Created: 2017-12-19T11:58:32.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2024-06-14T08:25:27.000Z (5 months ago)
- Last Synced: 2024-07-14T10:07:29.949Z (4 months ago)
- Topics: dsl, julia, query, repo, sql
- Language: Julia
- Homepage:
- Size: 940 KB
- Stars: 163
- Watchers: 13
- Forks: 7
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE.md
Awesome Lists containing this project
README
# Octo.jl
| **Documentation** | **Build Status** |
|:-----------------------------------------:|:------------------------------------------------------------------:|
| [![][docs-latest-img]][docs-latest-url] | [![][actions-img]][actions-url] [![][codecov-img]][codecov-url] |`Octo.jl` is an SQL Query DSL in [Julia](https://julialang.org).
It also comes with a very useful tool called [Repo](https://github.com/wookay/Octo.jl#repo).
You could `Repo.get`, `Repo.insert!` `Repo.update!` `Repo.delete!` for many database drivers without hand-written SQL.It's influenced by [Ecto](https://github.com/elixir-ecto/ecto).
* ☕️ You can [make a donation](https://wookay.github.io/donate/) to support this project.
## SQL Query DSL
```julia
julia> using Octo.Adapters.SQLjulia> struct User
endjulia> Schema.model(User, table_name="users")
| primary_key | table_name |
| ------------- | ------------ |
| id | users |julia> u = from(User)
FromItem usersjulia> [SELECT * FROM u]
SELECT * FROM usersjulia> [SELECT (u.name, u.salary) FROM u]
SELECT name, salary FROM usersjulia> [SELECT * FROM u WHERE u.id == 2]
SELECT * FROM users WHERE id = 2julia> to_sql([SELECT * FROM u WHERE u.id == 2])
"SELECT * FROM users WHERE id = 2"
```![structured.svg](https://wookay.github.io/docs/Octo.jl/assets/octo/structured.svg)
## Repo
Current supported database drivers:
- PostgreSQL (via [LibPQ.jl](https://github.com/invenia/LibPQ.jl))
- SQLite (via [SQLite.jl](https://github.com/JuliaDatabases/SQLite.jl))
- MySQL (via [MySQL.jl](https://github.com/JuliaDatabases/MySQL.jl))
- DuckDB (via [duckdb/tools/juliapkg](https://github.com/duckdb/duckdb/tree/main/tools/juliapkg))```julia
julia> using Octo.Adapters.PostgreSQLjulia> Repo.debug_sql()
LogLevelDebugSQL::RepoLogLevel = -1julia> Repo.connect(
adapter = Octo.Adapters.PostgreSQL,
dbname = "postgresqltest",
user = "postgres",
)
Octo.Repo.Connection(false, "postgresqltest", Main.PostgreSQLLoader, PostgreSQL connection (CONNECTION_OK) with parameters:
user = postgres
passfile = /Users/wookyoung/.pgpass
dbname = postgresqltest
port = 5432
client_encoding = UTF8
options = -c DateStyle=ISO,YMD -c IntervalStyle=iso_8601 -c TimeZone=UTC
application_name = LibPQ.jl
sslmode = prefer
sslcompression = 0
gssencmode = disable
target_session_attrs = any)julia> struct Employee
endjulia> Schema.model(Employee, table_name="Employee", primary_key="ID")
| primary_key | table_name |
| ------------- | ------------ |
| ID | Employee |julia> Repo.execute([DROP TABLE IF EXISTS Employee])
[ Info: DROP TABLE IF EXISTS Employeejulia> Repo.execute(Raw("""
CREATE TABLE Employee (
ID SERIAL,
Name VARCHAR(255),
Salary FLOAT(8),
PRIMARY KEY (ID)
)"""))
┌ Info: CREATE TABLE Employee (
│ ID SERIAL,
│ Name VARCHAR(255),
│ Salary FLOAT(8),
│ PRIMARY KEY (ID)
└ )julia> Repo.insert!(Employee, [
(Name="Jeremy", Salary=10000.50),
(Name="Cloris", Salary=20000.50),
(Name="John", Salary=30000.50),
(Name="Hyunden", Salary=40000.50),
(Name="Justin", Salary=50000.50),
(Name="Tom", Salary=60000.50),
])
[ Info: INSERT INTO Employee (Name, Salary) VALUES ($1, $2) RETURNING ID (Name = "Jeremy", Salary = 10000.5), (Name = "Cloris", Salary = 20000.5), (Name = "John", Salary = 30000.5), (Name = "Hyunden", Salary = 40000.5), (Name = "Justin", Salary = 50000.5), (Name = "Tom", Salary = 60000.5)
| id | num_affected_rows |
| ---- | ------------------- |
| 6 | 6 |julia> Repo.get(Employee, 2)
[ Info: SELECT * FROM Employee WHERE ID = 2
| id | name | salary |
| ---- | -------- | --------- |
| 2 | Cloris | 20000.5 |
1 row.julia> Repo.get(Employee, 2:5)
[ Info: SELECT * FROM Employee WHERE ID BETWEEN 2 AND 5
| id | name | salary |
| ---- | --------- | --------- |
| 2 | Cloris | 20000.5 |
| 3 | John | 30000.5 |
| 4 | Hyunden | 40000.5 |
| 5 | Justin | 50000.5 |
4 rows.julia> Repo.get(Employee, (Name="Jeremy",))
[ Info: SELECT * FROM Employee WHERE Name = 'Jeremy'
| id | name | salary |
| ---- | -------- | --------- |
| 1 | Jeremy | 10000.5 |
1 row.julia> Repo.query(Employee)
[ Info: SELECT * FROM Employee
| id | name | salary |
| ---- | --------- | --------- |
| 1 | Jeremy | 10000.5 |
| 2 | Cloris | 20000.5 |
| 3 | John | 30000.5 |
| 4 | Hyunden | 40000.5 |
| 5 | Justin | 50000.5 |
| 6 | Tom | 60000.5 |
6 rows.julia> Repo.insert!(Employee, (Name="Jessica", Salary=70000.50))
[ Info: INSERT INTO Employee (Name, Salary) VALUES ($1, $2) RETURNING ID (Name = "Jessica", Salary = 70000.5)
| id | num_affected_rows |
| ---- | ------------------- |
| 7 | 1 |julia> Repo.update!(Employee, (ID=2, Salary=85000))
[ Info: UPDATE Employee SET Salary = $1 WHERE ID = 2 85000
| num_affected_rows |
| ------------------- |
| 1 |julia> Repo.delete!(Employee, (ID=3,))
[ Info: DELETE FROM Employee WHERE ID = 3
| num_affected_rows |
| ------------------- |
| 1 |julia> Repo.delete!(Employee, 3:5)
[ Info: DELETE FROM Employee WHERE ID BETWEEN 3 AND 5
| num_affected_rows |
| ------------------- |
| 2 |julia> em = from(Employee)
FromItem Employeejulia> Repo.query(em)
[ Info: SELECT * FROM Employee
| id | name | salary |
| ---- | --------- | --------- |
| 1 | Jeremy | 10000.5 |
| 6 | Tom | 60000.5 |
| 7 | Jessica | 70000.5 |
| 2 | Cloris | 85000.0 |
4 rows.julia> Repo.query([SELECT * FROM em WHERE em.Name == "Cloris"])
[ Info: SELECT * FROM Employee WHERE Name = 'Cloris'
| id | name | salary |
| ---- | -------- | --------- |
| 2 | Cloris | 85000.0 |
1 row.julia> Repo.query(em, (Name="Cloris",))
[ Info: SELECT * FROM Employee WHERE Name = 'Cloris'
| id | name | salary |
| ---- | -------- | --------- |
| 2 | Cloris | 85000.0 |
1 row.julia> ❓ = Octo.PlaceHolder
PlaceHolderjulia> Repo.query([SELECT * FROM em WHERE em.Name == ❓], ["Cloris"])
[ Info: SELECT * FROM Employee WHERE Name = $1 "Cloris"
| id | name | salary |
| ---- | -------- | --------- |
| 2 | Cloris | 85000.0 |
1 row.
```### Subqueries
```julia
julia> sub = from([SELECT * FROM em WHERE em.Salary > 30000], :sub)
SubQuery (SELECT * FROM Employee WHERE Salary > 30000) AS subjulia> Repo.query(sub)
[ Info: SELECT * FROM Employee WHERE Salary > 30000
| id | name | salary |
| ---- | --------- | --------- |
| 6 | Tom | 60000.5 |
| 7 | Jessica | 70000.5 |
| 2 | Cloris | 85000.0 |
3 rows.julia> Repo.query([SELECT sub.Name FROM sub])
[ Info: SELECT sub.Name FROM (SELECT * FROM Employee WHERE Salary > 30000) AS sub
| name |
| --------- |
| Tom |
| Jessica |
| Cloris |
3 rows.
```## Colored SQL statements
![colored_sql_statements.png](https://raw.github.com/wookay/Octo.jl/master/docs/images/colored_sql_statements.png)
## Requirements
You need [Julia](https://julialang.org/downloads/).
`julia>` type `]` key
```julia
(v1.8) pkg> add Octo
``````julia
(v1.8) pkg> add LibPQ # for PostgreSQL (depends on LibPQ.jl 1.6, 1.7)
(v1.8) pkg> add SQLite # for SQLite (depends on SQLite.jl 1.6)
(v1.8) pkg> add MySQL # for MySQL (depends on MySQL.jl 1.1, 1.4)
(v1.8) pkg> add DuckDB # for DuckDB (depends on DuckDB.jl 1.0)
```See also [DBInterface.jl](https://github.com/JuliaDatabases/DBInterface.jl).
[docs-latest-img]: https://img.shields.io/badge/docs-latest-blue.svg
[docs-latest-url]: https://wookay.github.io/docs/Octo.jl/[actions-img]: https://github.com/wookay/Octo.jl/workflows/CI/badge.svg
[actions-url]: https://github.com/wookay/Octo.jl/actions[codecov-img]: https://codecov.io/gh/wookay/Octo.jl/branch/master/graph/badge.svg
[codecov-url]: https://codecov.io/gh/wookay/Octo.jl