{"id":15350056,"url":"https://github.com/takezoe/tranquil","last_synced_at":"2025-04-14T23:36:25.566Z","repository":{"id":57723485,"uuid":"87295382","full_name":"takezoe/tranquil","owner":"takezoe","description":"Type-safe SQL builder for Scala","archived":false,"fork":false,"pushed_at":"2019-07-18T08:26:51.000Z","size":162,"stargazers_count":31,"open_issues_count":7,"forks_count":4,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-28T11:42:48.759Z","etag":null,"topics":["database","jdbc","scala","sql"],"latest_commit_sha":null,"homepage":null,"language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/takezoe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-05T10:10:23.000Z","updated_at":"2024-11-21T13:09:05.000Z","dependencies_parsed_at":"2022-08-28T14:00:18.869Z","dependency_job_id":null,"html_url":"https://github.com/takezoe/tranquil","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/takezoe%2Ftranquil","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/takezoe%2Ftranquil/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/takezoe%2Ftranquil/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/takezoe%2Ftranquil/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/takezoe","download_url":"https://codeload.github.com/takezoe/tranquil/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248980730,"owners_count":21193136,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","jdbc","scala","sql"],"created_at":"2024-10-01T11:56:52.478Z","updated_at":"2025-04-14T23:36:25.539Z","avatar_url":"https://github.com/takezoe.png","language":"Scala","readme":"# Tranquil [![Build Status](https://travis-ci.org/takezoe/tranquil.svg?branch=master)](https://travis-ci.org/takezoe/tranquil) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.takezoe/tranquil_2.12/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.takezoe/tranquil_2.12)\n\nTranquil an experiment of type-safe SQL builder for Scala.\n\n```scala\nlibraryDependencies += \"com.github.takezoe\" %% \"tranquil\" % \"1.0.2\"\n```\n\n## Usage\n\nFirst, ready table definitions like following:\n\n```scala\nimport com.github.takezoe.tranquil._\nimport java.sql.ResultSet\n\ncase class User(userId: String, userName: String, companyId: Option[Int])\n\nclass Users extends TableDef[User](\"USERS\") {\n  val userId    = new Column[String](this, \"USER_ID\")\n  val userName  = new Column[String](this, \"USER_NAME\")\n  val companyId = new OptionalColumn[Int](this, \"COMPANY_ID\")\n\n  override def toModel(rs: ResultSet): User = {\n    User(userId.get(rs), userName.get(rs), companyId.get(rs))\n  }\n}\n\ncase class Company(companyId: Int, companyName: String)\n\nclass Companies extends TableDef[Company](\"COMPANIES\") {\n  val companyId   = new Column[Int](this, \"COMPANY_ID\")\n  val companyName = new Column[String](this, \"COMPANY_NAME\")\n\n  override def toModel(rs: ResultSet): Company = {\n    Company(companyId.get(rs), companyName.get(rs))\n  }\n}\n\nobject Tables {\n  val Users = new SingleTableAction[Users, User](new Users())\n  val Companies = new SingleTableAction[Companies, Company](new Companies())\n}\n```\n\nThen you can assemble SQL using type-safe DSL.\n\n```scala\nimport com.github.takezoe.tranquil._\nimport com.github.takezoe.tranquil.Dialect.generic\nimport Tables._\n\nval conn: java.sql.Connection = ...\n\n// SELECT\nval users: Seq[(User, Option[Company])] =\n  Users\n    .leftJoin(Companies){ case u ~ c =\u003e u.companyId eq c.companyId }\n    .filter { case u ~ c =\u003e (u.userId eq \"takezoe\") || (u.userId eq \"takezoen\") }\n    .sortBy { case u ~ c =\u003e u.userId asc }\n    .list(conn)\n```\n\nGenerated SQL is:\n\n```sql\nSELECT\n  u.USER_ID      AS u_USER_ID,\n  u.USER_NAME    AS u_USER_NAME,\n  u.COMPANY_ID   AS u_COMPANY_ID,\n  c.COMPANY_ID   AS c_COMPANY_ID,\n  c.COMPANY_NAME AS c_COMPANY_NAME\nFROM USERS u\nLEFT JOIN COMPANIES c ON u.COMPANY_ID = c.COMPANY_ID\nWHERE (u.USER_ID = ? OR u.USER_ID = ?)\nORDER BY u.USER_ID ASC\n```\n\nGrouping and aggregation are possible as follows:\n\n```scala\nval counts: Seq[(Option[Int], Long)] = \n  Users\n    .groupBy { t =\u003e t.companyId ~ t.userId.count }\n    .filter  { case companyId ~ count =\u003e count ge 10 }\n    .list(conn)\n```\n\nAlso you can assemble insert, update and delete SQL in the same way.\n\n```scala\n// INSERT\nUsers\n  .insert { u =\u003e \n    (u.userId -\u003e \"takezoe\") ~ \n    (u.userName -\u003e \"Naoki Takezoe\")\n  }\n  .execute(conn)\n\n// UPDATE\nUsers\n  .update(_.userName -\u003e \"N. Takezoe\")\n  .filter(_.userId eq \"takezoe\")\n  .execute(conn)\n\n// DELETE\nUsers\n  .delete()\n  .filter(_.userId eq \"takezoe\")\n  .execute(conn)\n```\n\n## Code generator\n\nTranquil has a code generator to generate case classes and table definitions like explained above from database schema. You can run the code generator as follows:\n\n```scala\nimport com.github.takezoe.tranquil.codegen._\n\nCodeGenerator.generate(Settings(\n  url       = \"jdbc:h2:mem:test;TRACE_LEVEL_FILE=4\",\n  driver    = \"org.h2.Driver\",\n  username  = \"sa\",\n  password  = \"sa\"\n))\n```\n\nSource files would be generated into `/src/main/scala/models/Tables.scala` in default.\n\nIn addition, you can configure the code generator via `Settings` which is passed to `CodeGenerator`. `Settings` has following properties:\n\nproperty           | type            | description\n-------------------|-----------------|------------------------------------------------\ndriver             | String          | JDBC driver classname (required)\nurl                | String          | JDBC connection url (required)\nusername           | String          | JDBC connection username (required)\npassword           | String          | JDBC connection password (required)\ncatalog            | String          | catalog (default is \"%\")\nschemaPattern      | String          | schema pattern (default is \"%\")\ntablePattern       | String          | table pattern (default is \"%\")\nincludeTablePattern| String          | regular expression which matches included tables (default is \"\")\nexcludeTablePattern| String          | regular expression which matches excluded tables (default is \"\")\npackageName        | String          | package name of generated source (default is \"models\")\ntargetDir          | File            | output directory of generated source (default is new File(\"src/main/scala\"))\ncharset            | String          | chaarset of generated source (default is \"UTF-8\")\ntypeMappings       | Map[Int, String]| mappings of SQL type to Scala type (default is DataTypes.defaultMappings)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftakezoe%2Ftranquil","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftakezoe%2Ftranquil","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftakezoe%2Ftranquil/lists"}