### Quick Reference Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md A concise reference guide for common ScalaSqL tasks, including setup, table definition syntax, query patterns, operators, transactions, raw SQL, and frequently used operations. ```APIDOC ## Quick Reference ### Description This section serves as a quick lookup for essential ScalaSqL syntax, patterns, and operations, designed for rapid development and reference. ### Key Areas Covered - **Setup and Configuration**: Initializing the database client and basic configuration. - **Table Definition**: Syntax for mapping Scala case classes to database tables. - **Basic Query Patterns**: Common ways to construct `SELECT` statements. - **Operators Reference**: Quick lookup for comparison, boolean, numeric, string, NULL, and casting operators. - **Set Operations**: Syntax for `union`, `intersect`, `except`. - **Transactions and Savepoints**: Basic usage for managing transaction boundaries. - **Raw SQL**: How to embed and execute raw SQL strings. - **Streaming**: Using streams for efficient result set processing. - **Window Functions**: Common window function patterns. - **Common Operations**: Examples for tasks like finding by ID, counting rows, pagination, and selecting distinct values. - **Common Patterns**: Solutions for batch import, conditional filters, upserts, and audit trails. ``` -------------------------------- ### Complete Configuration Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/06-type-mappers-and-config.md A comprehensive example demonstrating configuration for name mapping, conditional SQL logging, default fetch size, and query timeouts, along with setting up a `DbClient`. ```scala import scalasql.* import scalasql.PostgresDialect.* val config = new Config { // Convert to lowercase without snake_case override def nameMapper(v: String) = v.toLowerCase() // Only log queries in development override def logSql(sql: String, file: String, line: Int): Unit = { if (isDevelopment) { logger.info(s"[$file:$line] $sql") } } // Use reasonable defaults for streaming override def defaultFetchSize = 5000 override def defaultQueryTimeoutSeconds = 60 } val dataSource = new org.postgresql.ds.PGSimpleDataSource dataSource.setURL("jdbc:postgresql://localhost/mydb") dataSource.setUser("user") dataSource.setPassword("password") val dbClient = new DbClient.DataSource(dataSource, config = config) dbClient.transaction { db => val users = db.run(User.select) // Log: [MyCode.scala:42] SELECT ... FROM user } ``` -------------------------------- ### Example 1: Basic CRUD Operations Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md A comprehensive example demonstrating basic Create, Read, Update, and Delete operations using Scalasql. ```Scala // Create db.run(users.insert(users.name -> "Alice", users.age -> 30)) // Read val alice = db.run(select(users.name, users.age).from(users).where(users.name == "Alice")).headOption // Update db.run(users.update(users.age -> 31).where(users.name == "Alice")) // Delete db.run(users.delete.where(users.name == "Alice")) ``` -------------------------------- ### Setup and Configuration Reference Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Quick reference for setting up Scalasql and configuring its behavior. ```Scala // Basic setup with HikariCP connection pool val dataSource = new HikariDataSource(new HikariConfig() { setJdbcUrl("jdbc:postgresql://localhost:5432/mydb") setUsername("user") setPassword("password") }) val db = new JdbcDbClient(dataSource) ``` -------------------------------- ### Complete Examples Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md A collection of practical examples demonstrating various ScalaSqL features, from basic CRUD operations and joins to advanced use cases like transactions, raw SQL, and upserts. ```APIDOC ## Complete Examples ### Description This section provides a practical guide to using ScalaSqL through a series of end-to-end examples covering a wide range of functionalities. ### Example Scenarios 1. **Basic CRUD**: Demonstrates standard Create, Read, Update, and Delete operations. 2. **Multi-table Queries**: Illustrates how to perform queries involving joins across multiple tables. 3. **Aggregation and Grouping**: Shows how to use aggregate functions with `groupBy`. 4. **Window Functions**: Examples of using analytical window functions. 5. **Batch Operations**: Demonstrates efficient batch inserts and updates. 6. **Transactions with Savepoints**: Illustrates complex transaction management, including partial rollbacks. 7. **Custom Configuration and Logging**: Examples of setting up custom type mappers, name mappers, and enabling SQL logging. 8. **Raw SQL Execution**: How to execute arbitrary SQL strings when needed. 9. **Upsert on Conflict**: Implementing `ON CONFLICT` logic for handling unique constraint violations. 10. **Performance Optimization**: Techniques and examples for optimizing query performance. ``` -------------------------------- ### Import ScalaSql and H2 Dialect Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/tutorial.md Import necessary ScalaSql components and the H2 database dialect to begin using the library. This setup is suitable for examples using the H2 database. ```scala import scalasql.* import scalasql.H2Dialect._ ``` -------------------------------- ### Example 6: Transactions with Savepoints Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md An example showing how to use transactions and savepoints for managing partial rollbacks. ```Scala db.transaction { implicit txn => txn.savepoint("before_update") txn.run(users.update(users.age -> 32).where(users.name == "Alice")) // Potentially rollback to "before_update" if an error occurs } ``` -------------------------------- ### Database Setup Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/11-quick-reference.md Configure your database connection using a DataSource. Choose the appropriate dialect for your database. ```scala import scalasql.* import scalasql.PostgresDialect. * val dataSource = new org.postgresql.ds.PGSimpleDataSource dataSource.setURL("jdbc:postgresql://localhost/mydb") val dbClient = new DbClient.DataSource(dataSource) ``` -------------------------------- ### Example 7: Custom Configuration and Logging Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Illustrates setting up custom configuration, including SQL logging. ```Scala val customConfig = Config.default.copy( defaultFetchSize = Some(500), logSql = true ) val db = new JdbcDbClient(connection, customConfig) ``` -------------------------------- ### Example 4: Window Functions Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md An example illustrating the use of window functions to perform calculations across a set of table rows. ```Scala val q = select( users.name, ROW_NUMBER() over (partitionBy(users.country).orderBy(users.age.desc)) ).from(users) db.run(q) ``` -------------------------------- ### Example 3: Aggregation and Grouping Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Shows an example of calculating aggregate values (e.g., count, average) grouped by a specific column. ```Scala val q = select(users.country, count(users.id)).from(users).groupBy(users.country) db.run(q) ``` -------------------------------- ### Example 5: Batch Operations Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Demonstrates performing batch inserts for efficient insertion of multiple records. ```Scala val data = Seq(User(0, "Batch1", 10), User(0, "Batch2", 20)) db.run(users.insert.batched(data, (row, user) => row.set(users.name, user.name).set(users.age, user.age))) ``` -------------------------------- ### Example 10: Performance Optimization Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Discusses performance optimization techniques, such as streaming and batch operations. ```Scala // Using streaming for large result sets db.stream(select.from(users)).foreach(println) // Using batch inserts for multiple records val usersToInsert = Seq(("Bob", 25), ("Charlie", 35)) db.run(users.insert(users.name, users.age).batched(usersToInsert, (row, data) => row.set(data._1, data._2))) ``` -------------------------------- ### OUTPUT Clause Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/07-dialects.md Demonstrates the use of the OUTPUT clause, similar to RETURNING, which is translated for SQL Server. ```scala db.run( User.update(_.id === 1) .set(_.name := "Updated") .returning(u => u) ) // Translates to OUTPUT clause for SQL Server ``` -------------------------------- ### Optional.mapGet Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Illustrates using map and get to transform optional values. Using .get on an optional column results in SQL NULL semantics. ```scala OptCols.select.map(d => d.copy[Expr](myInt = d.myInt.map(_ + d.myInt2.get + 1))) ``` ```sql SELECT ((opt_cols0.my_int + opt_cols0.my_int2) + ?) AS my_int, opt_cols0.my_int2 AS my_int2 FROM opt_cols opt_cols0 ``` ```scala Seq( OptCols[Sc](None, None), OptCols[Sc](Some(4), Some(2)), // because my_int2 is added to my_int, and my_int2 is null, my_int becomes null too OptCols[Sc](None, None), OptCols[Sc](None, Some(4)) ) ``` -------------------------------- ### Import Database Dialect Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/00-index.md Import the appropriate dialect for your database. Examples include PostgresDialect, MySqlDialect, and SqliteDialect. ```scala import scalasql.PostgresDialect.* // or MySqlDialect, SqliteDialect, etc. ``` -------------------------------- ### Example 2: Multi-table Queries with Joins Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Demonstrates how to perform queries involving multiple tables using various join types. ```Scala val q = for { u <- users a <- addresses if u.id == a.userId } yield (u.name, a.street) db.run(q) ``` -------------------------------- ### Squeryl SQL-like API Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/design.md Illustrates Squeryl's approach to filtering and subqueries using a more SQL-centric DSL. ```scala def songs = from(MusicExpr.songs)(s => where(s.artistId === id) select(s)) val studentsWithAnAddress = from(students)(s => where(exists(from(addresses)((a) => where(s.addressId === a.id) select(a.id)))) select(s) ) ``` -------------------------------- ### Use SQLite Dialect Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/07-dialects.md Import and configure the SQLite dialect. This example shows setting up an SQLite DataSource for an in-memory or file-based database. ```scala import scalasql.SqliteDialect.* val dataSource = new org.sqlite.SQLiteDataSource dataSource.setUrl("jdbc:sqlite:mydb.db") val dbClient = new DbClient.DataSource(dataSource) ``` -------------------------------- ### Advanced Setup for Option Columns Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Sets up a table with Option columns for advanced testing. Demonstrates inserting rows with a mix of Some and None values. ```scala OptCols.insert.batched(_.myInt, _.myInt2)( (Some(1), Some(1)), (Some(2), None), (Some(3), Some(3)), (None, Some(4)), (Some(5), Some(5)) ) ``` ```scala 5 ``` -------------------------------- ### Use PostgreSQL Dialect Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/07-dialects.md Import and use the PostgreSQL dialect for database operations. This example shows setting up a DataSource and running a query. ```scala import scalasql.PostgresDialect.* val dbClient = new DbClient.DataSource( new org.postgresql.ds.PGSimpleDataSource { /* config */ } ) dbClient.transaction { db => val result = db.run(User.select) // Generates PostgreSQL-specific SQL } ``` -------------------------------- ### Scala Query Styles Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/cheatsheet.md Examples of executing select and update queries using Scala-native syntax with ScalaSql. ```scala val str = "hello" // Select Query db.run(Foo.select.filter(_.myStr === str)): Seq[Foo[Id]] // Update Query db.run(Foo.update(_.myStr === str).set(_.myInt := 123)): Int ``` -------------------------------- ### Use Microsoft SQL Server Dialect Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/07-dialects.md Import and configure the Microsoft SQL Server dialect. This example shows setting up the SQL Server DataSource. ```scala import scalasql.MsSqlDialect.* val dataSource = new com.microsoft.sqlserver.jdbc.SQLServerDataSource { /* config */ } val dbClient = new DbClient.DataSource(dataSource) ``` -------------------------------- ### Production: MySQL Dialect Import Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/07-dialects.md Example import for using the MySQL dialect in production, suitable for existing MySQL deployments. ```scala import scalasql.MySqlDialect.* // Good for existing MySQL deployments ``` -------------------------------- ### Raw Query Styles Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/cheatsheet.md Examples of executing select and update queries using raw SQL strings with parameter binding. ```scala // Raw Select Query db.runRaw[Foo[Id]]("SELECT * FROM foo WHERE foo.my_str = ?", Seq(str)): Seq[Foo[Id]] // Raw Update Query db.updateRaw("UPDATE foo SET my_int = 123 WHERE foo.my_str = ?", Seq(str)): Int ``` -------------------------------- ### MsSqlDialect.top Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Translates the `.take(n)` operator to a SQL `TOP(n)` clause for Microsoft SQL Server. ```scala Buyer.select.take(0) ``` ```sql SELECT TOP(?) buyer0.id AS id, buyer0.name AS name, buyer0.date_of_birth AS date_of_birth FROM buyer buyer0 ``` ```scala Seq[Buyer[Sc]]() ``` -------------------------------- ### Window Functions in Advanced Features Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Provides examples of using window functions (ROW_NUMBER, RANK, LAG, LEAD) with partitioning and ordering. ```Scala val q = select( users.name, RANK() over (partitionBy(users.country).orderBy(users.age.desc)) ).from(users) ``` -------------------------------- ### Production: PostgreSQL Dialect Import Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/07-dialects.md Example import for using the PostgreSQL dialect in production, noted for its best feature support. ```scala import scalasql.PostgresDialect.* // Best feature support, most reliable ``` -------------------------------- ### Example 8: Raw SQL Execution Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Demonstrates executing a raw SQL query using the sql"..." string interpolator. ```Scala val userId = 1 val q = sql"SELECT name FROM users WHERE id = ${userId}" db.run(q) ``` -------------------------------- ### Queryable.walkLabels Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/09-queryable-trait.md Demonstrates how to retrieve the column labels for a query, showing the nested structure as a sequence of string paths. ```scala User.select.walkLabels() // Seq(List("id"), List("name"), List("email")) (User.select.map(u => (u.id, u.name))).walkLabels() // Seq(List("id"), List("name")) ``` -------------------------------- ### ScalaSql Collection-like API Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/design.md Demonstrates ScalaSql's filter operations using a syntax similar to Scala collections. ```scala def songs = MusicExpr.songs.filter(_.artistId === id) val studentsWithAnAddress = students.filter(s => addresses.filter(a => s.addressId === a.id).nonEmpty) ``` -------------------------------- ### SQL Query Styles Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/cheatsheet.md Examples of executing select and update queries using raw SQL strings interpolated with ScalaSql. ```scala // SQL Select Query db.runSql[Seq[Foo[Id]]](sql"SELECT * FROM foo WHERE foo.my_str = $str"): Seq[Foo[Id]] // SQL Update Query db.updateSql(sql"UPDATE foo SET my_int = 123 WHERE foo.my_str = $str"): Int ``` -------------------------------- ### Optional.sorting.nullsFirst Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Demonstrates sorting by an optional column with NULLs appearing first. This translates to the SQL 'ORDER BY ... NULLS FIRST' clause. ```scala OptCols.select.sortBy(_.myInt).nullsFirst ``` ```sql SELECT opt_cols0.my_int AS my_int, opt_cols0.my_int2 AS my_int2 FROM opt_cols opt_cols0 ORDER BY my_int NULLS FIRST ``` ```scala Seq( OptCols[Sc](None, None), OptCols[Sc](None, Some(4)), OptCols[Sc](Some(1), Some(2)), OptCols[Sc](Some(3), None) ) ``` -------------------------------- ### Streaming Query Styles Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/cheatsheet.md Examples of streaming select query results using Scala-native, SQL, and raw SQL methods. ```scala // Streaming Select Query db.stream(Foo.select.filter(_.myStr === str)): Generator[Foo[Id]] // Streaming SQL Select Query db.streamSql[Foo[Id]](sql"SELECT * FROM foo WHERE foo.my_str = $str"): Generator[Foo[Id]] // Streaming SQL Select Query db.streamRaw[Foo[Id]]("SELECT * FROM foo WHERE foo.my_str = ?", Seq(str)): Generator[Foo[Id]] ``` -------------------------------- ### ExprBlobOps.startsWith Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Checks if a byte array expression starts with a specified prefix. This operation translates to a LIKE clause in SQL. ```APIDOC ## ExprBlobOps.startsWith ### Description Checks if a byte array expression starts with a specified prefix. This operation translates to a LIKE clause in SQL. ### Method N/A (Scala method) ### Endpoint N/A (Scala method) ### Parameters N/A (Scala method parameters are implicit in the example) ### Request Example ```scala Expr(Bytes("Hello")).startsWith(Bytes("Hel")) ``` ### Response #### Success Response - **res** (Boolean) - True if the byte array starts with the prefix, false otherwise. #### Response Example ```scala true ``` ``` -------------------------------- ### Production: MSSQL Dialect Import Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/07-dialects.md Example import for using the MSSQL dialect in production, intended for enterprise SQL Server environments. ```scala import scalasql.MsSqlDialect.* // For enterprise SQL Server environments ``` -------------------------------- ### Substring Extraction Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/04-expressions-and-operators.md Extracts a portion of a string expression based on start position and length, or just start position. ```scala def substring(start: Int, length: Int): Expr[T] def substring(start: Expr[Int]): Expr[T] ``` ```scala db.run(User.select.map(u => u.email.substring(0, 5))) ``` -------------------------------- ### Optional.sorting.nullsLast Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Shows how to sort by an optional column with NULLs appearing last. This translates to the SQL 'ORDER BY ... NULLS LAST' clause. ```scala OptCols.select.sortBy(_.myInt).nullsLast ``` ```sql SELECT opt_cols0.my_int AS my_int, opt_cols0.my_int2 AS my_int2 FROM opt_cols opt_cols0 ORDER BY my_int NULLS LAST ``` ```scala Seq( OptCols[Sc](Some(1), Some(2)), OptCols[Sc](Some(3), None), OptCols[Sc](None, None), OptCols[Sc](None, Some(4)) ) ``` -------------------------------- ### Optional.rawGet Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Shows direct use of .get to access optional values. This operation assumes the value is present and will error if it's None. ```scala OptCols.select.map(d => d.copy[Expr](myInt = d.myInt.get + d.myInt2.get + 1)) ``` ```sql SELECT ((opt_cols0.my_int + opt_cols0.my_int2) + ?) AS my_int, opt_cols0.my_int2 AS my_int2 FROM opt_cols opt_cols0 ``` ```scala Seq( OptCols[Sc](None, None), OptCols[Sc](Some(4), Some(2)), // because my_int2 is added to my_int, and my_int2 is null, my_int becomes null too OptCols[Sc](None, None), OptCols[Sc](None, Some(4)) ) ``` -------------------------------- ### Scala Blob Starts With Operation Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Checks if a blob expression starts with a specified prefix. The SQL equivalent uses the LIKE operator with a wildcard. ```scala Expr(Bytes("Hello")).startsWith(Bytes("Hel")) ``` ```sql SELECT (? LIKE ? || '%') AS res ``` ```scala true ``` -------------------------------- ### Query Composition Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/02-select-query.md Demonstrates a complex query composed of multiple operations including filtering, joining, mapping, sorting, distinctness, and limiting. ```APIDOC ## Query Composition Example ### Description Complex query with multiple operations. ### Example ```scala // Complex query with multiple operations val result = db.run( User.select .filter(_.age > 18) .filter(_.isActive === true) .join(Post)((u, p) => u.id === p.userId) .map { case (u, p) => (u.name, p.title) } .sortBy(_._1).asc .distinct .take(10) ) ``` This generates: ```sql SELECT DISTINCT user0.name, post0.title FROM user user0 INNER JOIN post post0 ON user0.id = post0.user_id WHERE user0.age > ? AND user0.is_active = true ORDER BY user0.name ASC LIMIT 10 ``` ``` -------------------------------- ### Testing: H2 Data Source with PostgreSQL Mode Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/07-dialects.md Setup for using an H2 in-memory database in PostgreSQL compatibility mode for testing. ```scala import scalasql.H2Dialect.* val dataSource = new org.h2.jdbcx.JdbcDataSource dataSource.setURL("jdbc:h2:mem:test;MODE=PostgreSQL") ``` -------------------------------- ### Get the length of a string Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Use the `length` method on a string expression to get its character length. This corresponds to SQL's `LENGTH` function. ```scala Expr("hello").length ``` ```sql SELECT LENGTH(?) AS res ``` ```text 5 ``` -------------------------------- ### Get the octet length of a string Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Use the `octetLength` method on a string expression to get its length in bytes. This corresponds to SQL's `OCTET_LENGTH` function. ```scala Expr("叉烧包").octetLength ``` ```sql SELECT OCTET_LENGTH(?) AS res ``` ```text 9 ``` -------------------------------- ### Full Test Suite with Documentation Generation Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/developer.md Execute the full test suite and regenerate documentation, including tutorials and reference materials. Note that reference documentation is extracted from the test suite. ```bash ./mill -ij1 "__.test" + generateTutorial + generateReference ``` -------------------------------- ### Get Nth Value in Partition with NTH_VALUE Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Retrieves the Nth value in an ordered partition. Specify the desired position (N) to get a specific value from the sequence within a group. ```scala Purchase.select.map(p => ( p.shippingInfoId, p.total, db.nthValue(p.total, 2).over.partitionBy(p.shippingInfoId).sortBy(p.total).asc ) ) ``` ```sql SELECT purchase0.shipping_info_id AS res_0, purchase0.total AS res_1, NTH_VALUE(purchase0.total, ?) OVER (PARTITION BY purchase0.shipping_info_id ORDER BY purchase0.total ASC) AS res_2 FROM purchase purchase0 ``` ```scala Seq[(Int, Double, Double)]( (1, 15.7, 0.0), (1, 888.0, 888.0), (1, 900.0, 888.0), (2, 493.8, 0.0), (2, 10000.0, 10000.0), (3, 1.3, 0.0), (3, 44.4, 44.4) ) ``` -------------------------------- ### Use MySQL Dialect Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/07-dialects.md Import and configure the MySQL dialect. This snippet demonstrates setting up the MySQL DataSource. ```scala import scalasql.MySqlDialect.* val dbClient = new DbClient.DataSource( new com.mysql.cj.jdbc.MysqlDataSource { /* config */ } ) ``` -------------------------------- ### H2Dialect.rpad Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Pads a string on the right to a specified length using RPAD in H2. ```scala Expr("Hello").rpad(10, "xy") ``` ```sql SELECT RPAD(?, ?, ?) AS res ``` ```scala "Helloxxxxx" ``` -------------------------------- ### H2Dialect.lpad Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Pads a string on the left to a specified length using LPAD in H2. ```scala Expr("Hello").lpad(10, "xy") ``` ```sql SELECT LPAD(?, ?, ?) AS res ``` ```scala "xxxxxHello" ``` -------------------------------- ### Selecting All Columns from a Table Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/05-table-definition.md Demonstrates how to initiate a SELECT query on a table to retrieve all its columns. ```scala User.select // Selects all columns from user table ``` -------------------------------- ### SqliteDialect.zeroBlob Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Creates a zero-filled blob of a specified size using the ZEROBLOB function in SQLite. ```scala db.zeroBlob(16) ``` ```sql SELECT ZEROBLOB(?) AS res ``` ```scala new geny.Bytes(new Array[Byte](16)) ``` -------------------------------- ### SqliteDialect.unhex Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Converts a hexadecimal string to a byte array using the UNHEX function in SQLite. ```scala db.unhex("010A6481") ``` ```sql SELECT UNHEX(?) AS res ``` ```scala new geny.Bytes(Array(1, 10, 100, -127)) ``` -------------------------------- ### SqliteDialect.char Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Converts integer character codes to a string using the CHAR function in SQLite. ```scala db.char(108, 111, 108) ``` ```sql SELECT CHAR(?, ?, ?) AS res ``` ```scala "lol" ``` -------------------------------- ### ON CONFLICT DO UPDATE (UPSERT) Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/03-insert-update-delete.md Handles duplicate key conflicts by updating the 'lastLogin' timestamp. ```scala db.run( User.insert.values(newUser) .onConflictDoUpdate(_.email)( _.lastLogin := Expr { implicit ctx => sql"NOW()" } ) ) // ON CONFLICT (email) DO UPDATE SET last_login = NOW() ``` -------------------------------- ### Select Query Creation Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Demonstrates the creation of SELECT queries in Scalasql. ```Scala val q = select(users.name, users.age) .from(users) .where(users.age > 21) .orderBy(users.age.desc) .limit(10) ``` -------------------------------- ### Delete Operations in ScalaSql Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/cheatsheet.md Example of deleting rows from a table based on a specified filter condition. ```scala Foo.delete(_.myStr === "hello") // Int // DELETE FROM foo WHERE foo.my_str = "hello" ``` -------------------------------- ### Get Distinct Values Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/11-quick-reference.md Extract unique values from a specific column using the `distinct` modifier. ```scala db.run(User.select.map(_.department).distinct) ``` -------------------------------- ### Basic Select Query Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/02-select-query.md Demonstrates how to create a basic SELECT query to retrieve all rows from a table. ```scala case class User[T[_]]( id: T[Int], name: T[String], age: T[Int] ) object User extends Table[User] // Select all rows val allUsers = User.select ``` -------------------------------- ### Count Records Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/11-quick-reference.md Get the total number of records in a table using the `aggregate(_.size)` method. ```scala db.run(User.select.aggregate(_.size)) ``` -------------------------------- ### Create a Database Client Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/00-index.md Instantiate a `DbClient` using a `DataSource`. This client is used to interact with the database. ```scala val dbClient = new DbClient.DataSource(dataSource) ``` -------------------------------- ### Get Number of Deleted Rows Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/03-insert-update-delete.md Executes a delete query and returns the count of rows affected. ```scala val deleted = db.run(User.delete(_.isActive === false)) println(s"Deleted $deleted rows") ``` -------------------------------- ### Run Quick Database-Specific Tests Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/developer.md Run all unit tests on a single specified database. This is significantly faster than running all tests and is ideal for quick iterations on non-database-specific changes. ```bash ./mill -i -w "__.test scalasql.sqlite" ``` -------------------------------- ### SqliteDialect.hex Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Converts a byte array to its hexadecimal string representation using the HEX function in SQLite. ```scala db.hex(new geny.Bytes(Array(1, 10, 100, -127))) ``` ```sql SELECT HEX(?) AS res ``` ```scala "010A6481" ``` -------------------------------- ### Column Naming and Customization Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Shows how to customize column names and add constraints like primary keys or nullability. ```Scala val userId = col("user_id", int).primaryKey.autoIncrement val email = col("email_address", varchar(255)).nullable ``` -------------------------------- ### DbCountOps.countWithGroupBy Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Counts records grouped by a specific column, with an example of counting distinct products within each group. ```APIDOC ## DbCountOps.countWithGroupBy ### Description Counts records grouped by a specific column. The example shows grouping by `shippingInfoId` and then counting distinct `productId` within each group. ### Method N/A (Scala DSL) ### Endpoint N/A (Scala DSL) ### Parameters N/A (Scala DSL) ### Request Example ```scala Purchase.select.groupBy(_.shippingInfoId)(agg => agg.countBy(_.productId)) ``` ### Response #### Success Response (200) Returns a sequence of tuples, where each tuple contains the grouping key and the count. #### Response Example ```scala Seq((1, 3), (2, 2), (3, 2)) ``` ``` -------------------------------- ### Table Names, Schemas, and Escaping Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Demonstrates how to specify table names, schemas, and handle SQL identifier escaping. ```Scala object "my-users" extends Table[User](?) { override val schemaName = "public" val id = col("id", int) // ... } ``` -------------------------------- ### Aggregation and Grouping Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Demonstrates how to perform aggregations (like count, sum, avg) and group results by specified columns. ```Scala val q = select(users.country, count(users.id)).from(users).groupBy(users.country) ``` -------------------------------- ### Error Handling with Transactions Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/00-index.md Provides an example of how to catch `SQLException` during a database transaction using a `try-catch` block. ```scala try { db.transaction { api => ... } } catch { case e: SQLException => logger.error(s"DB error: ${e.getMessage}") } ``` -------------------------------- ### ON CONFLICT DO NOTHING Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/03-insert-update-delete.md Handles duplicate key conflicts during insertion by doing nothing, specifically for the email column. ```scala // PostgreSQL/SQLite db.run( User.insert.values(newUser).onConflictDoNothing(_.email) ) // ON CONFLICT (email) DO NOTHING ``` -------------------------------- ### Default Configuration Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/00-index.md Create a default `Config` instance. This uses all default settings for the database connection. ```scala new Config {} // Uses all defaults ``` -------------------------------- ### ResultSetIterator Usage Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/09-queryable-trait.md Demonstrates how to use the ResultSetIterator to extract values of specific types from a JDBC ResultSet. ```scala val iterator = new Queryable.ResultSetIterator(resultSet) val id = iterator.get[Int] // Get first column as Int val name = iterator.get[String] // Get second column as String val age = iterator.get[Int] // Get third column as Int ``` -------------------------------- ### Mapping and Projection Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Illustrates how to map query results to case classes and project specific columns. ```Scala val q = select(users.name, users.age).from(users).as(users.name, users.age) ``` -------------------------------- ### MsSqlDialect.update BIT Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Updates BIT values in a table using the UPDATE statement in Microsoft SQL Server. ```scala BoolTypes .update(_.a `=` 1) .set(_.nonNullable := true) ``` ```sql UPDATE bool_types SET non_nullable = ? WHERE (bool_types.a = ?) ``` -------------------------------- ### Run All Unit Tests Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/developer.md Execute all unit tests for the project. This command is useful for a comprehensive test run. ```bash ./mill -i -w "__.test" ``` -------------------------------- ### Operator Precedence Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Demonstrates how operator precedence is handled in expressions. Parentheses are used to enforce order of operations. ```scala (Expr(2) + Expr(3)) * Expr(4) ``` ```sql SELECT ((? + ?) * ?) AS res ``` ```scala 20 ``` -------------------------------- ### Aggregate Functions Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Demonstrates common aggregate functions such as size, count, sum, avg, min, max, any, and all. ```Scala count(users.id) sum(users.salary) avg(users.age) min(users.created_at) max(users.salary) any(users.is_active) all(users.is_verified) ``` -------------------------------- ### Example 9: Upsert on Conflict Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Shows how to perform an upsert operation (insert or update) using the ON CONFLICT clause. ```Scala db.run(users.insertOrUpdate(users.id -> 1, users.name -> "Alice", users.age -> 33).onConflictIgnore) ``` -------------------------------- ### Initialize ScalaSql DbClient with Connection and Config Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/tutorial.md Initializes a ScalaSql `DbClient` using a `java.sql.Connection` and a `Config` object. It then retrieves an auto-committing client connection and executes SQL scripts to set up the database schema and data. ```scala val dbClient = new DbClient.Connection( java.sql.DriverManager .getConnection("jdbc:h2:mem:testdb" + scala.util.Random.nextInt(), "sa", ""), new Config { override def nameMapper(v: String) = v.toLowerCase() } ) val db = dbClient.getAutoCommitClientConnection db.updateRaw(os.read(os.Path(sys.env("MILL_TEST_RESOURCE_DIR")) / "world-schema.sql")) db.updateRaw(os.read(os.Path(sys.env("MILL_TEST_RESOURCE_DIR")) / "world-data.sql")) ``` -------------------------------- ### Right Join Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/tutorial.md Perform a right join between 'City' and 'Country' tables and filter for countries with no corresponding cities. ```scala val query = City.select .rightJoin(Country)(_.countryCode === _.code) .filter { case (cityOpt, country) => cityOpt.isEmpty(_.id) } .map { case (cityOpt, country) => (cityOpt.map(_.name), country.name) } db.renderSql(query) ==> """ SELECT city0.name AS res_0, country1.name AS res_1 FROM city city0 RIGHT JOIN country country1 ON (city0.countrycode = country1.code) WHERE (city0.id IS NULL) """ db.run(query) ==> Seq( (None, "Antarctica"), (None, "Bouvet Island"), (None, "British Indian Ocean Territory"), (None, "South Georgia and the South Sandwich Islands"), (None, "Heard Island and McDonald Islands"), (None, "French Southern territories"), (None, "United States Minor Outlying Islands") ) ``` -------------------------------- ### Initialize Schema, Data, and Query Population Source: https://github.com/com-lihaoyi/scalasql/blob/main/readme.md Initializes the database schema and data, then calculates the total population of cities in China. The SQL query generated is shown in comments. ```Scala dbClient.transaction{ db => // Initialize database table schema and data db.updateRaw(os.read(os.Path("scalasql/test/resources/world-schema.sql", os.pwd))) db.updateRaw(os.read(os.Path("scalasql/test/resources/world-data.sql", os.pwd))) // Adding up population of all cities in China val citiesPop = db.run(City.select.filter(_.countryCode === "CHN").map(_.population).sum) // SELECT SUM(city0.population) AS res FROM city city0 WHERE city0.countrycode = ? println(citiesPop) // 175953614 } ``` -------------------------------- ### Inner Join Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/tutorial.md Perform an inner join between 'City' and 'Country' tables to find cities in a specific country. ```scala val query = City.select .join(Country)(_.countryCode === _.code) .filter { case (city, country) => country.name === "Liechtenstein" } .map { case (city, country) => city.name } db.renderSql(query) ==> """ SELECT city0.name AS res FROM city city0 JOIN country country1 ON (city0.countrycode = country1.code) WHERE (country1.name = ?) """ db.run(query) ==> Seq("Schaan", "Vaduz") ``` -------------------------------- ### Selecting All Table Contents Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Shows how to select all contents of a table using `Table.select`. Be cautious as this can be expensive on large databases; prefer using filters. ```scala Buyer.select ``` -------------------------------- ### Raw SQL Execution Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Demonstrates executing raw SQL strings directly, bypassing Scalasql's query builder. ```Scala db.runRaw("DELETE FROM users WHERE age < 18") ``` ```Scala db.updateRaw("UPDATE users SET name = ? WHERE id = ?", "Alice", 1) ``` ```Scala val q = sql"SELECT * FROM users WHERE country = ${country}" ``` -------------------------------- ### Insert Operations in ScalaSql Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/cheatsheet.md Examples of inserting single rows with specified values and batched inserts for multiple rows. ```scala Foo.insert.values(_.myStr := "hello", _.myInt := 123) // 1 // INSERT INTO foo (my_str, my_int) VALUES ("hello", 123) Foo.insert.batched(_.myStr, _.myInt)(("a", 1), ("b", 2)) // 2 // INSERT INTO foo (my_str, my_int) VALUES ("a", 1), ("b", 2) ``` -------------------------------- ### Use H2 Dialect Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/07-dialects.md Import and configure the H2 dialect for testing. This snippet shows setting up an H2 in-memory DataSource. ```scala import scalasql.H2Dialect.* val dataSource = new org.h2.jdbcx.JdbcDataSource dataSource.setURL("jdbc:h2:mem:test") val dbClient = new DbClient.DataSource(dataSource) ``` -------------------------------- ### Optional.flatMap Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Demonstrates using flatMap to combine optional values. If any nested optional value is None, the result is None. ```scala OptCols.select .map(d => d.copy[Expr](myInt = d.myInt.flatMap(v => d.myInt2.map(v2 => v + v2 + 10)))) ``` ```sql SELECT ((opt_cols0.my_int + opt_cols0.my_int2) + ?) AS my_int, opt_cols0.my_int2 AS my_int2 FROM opt_cols opt_cols0 ``` ```scala Seq( OptCols[Sc](None, None), OptCols[Sc](Some(13), Some(2)), // because my_int2 is added to my_int, and my_int2 is null, my_int becomes null too OptCols[Sc](None, None), OptCols[Sc](None, Some(4)) ) ``` -------------------------------- ### Basic Selects in ScalaSql Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/cheatsheet.md Demonstrates basic select operations, including selecting all columns, specific columns, and mapped tuples. ```scala Foo.select // Seq[Foo[Id]] // SELECT * FROM foo Foo.select.map(_.myStr) // Seq[String] // SELECT my_str FROM foo Foo.select.map(t => (t.myStr, t.myInt)) // Seq[(String, Int)] // SELECT my_str, my_int FROM foo ``` -------------------------------- ### CASE/WHEN Expressions Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Shows how to construct CASE/WHEN expressions for conditional logic within SQL queries. ```Scala CASE WHEN users.age < 18 THEN "Minor" WHEN users.age >= 18 AND users.age < 65 THEN "Adult" ELSE "Senior" END ``` -------------------------------- ### Basic Query Patterns Reference Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Common patterns for constructing SELECT queries. ```Scala // Select all columns select.from(users) // Select specific columns select(users.name, users.age).from(users) // Filter results select.from(users).where(users.age > 18) ``` -------------------------------- ### DbClient.Connection Constructor Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/01-dbclient-api.md Instantiates a DbClient using a direct JDBC connection. Requires an implicit SQL dialect configuration. ```scala class Connection( connection: java.sql.Connection, config: Config = new Config {}, listeners: Seq[DbApi.TransactionListener] = Seq.empty )(implicit dialect: DialectConfig) extends DbClient ``` -------------------------------- ### Sort, Drop, and Take Results Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Combine `.drop` and `.take` to implement pagination. This translates to `LIMIT` and `OFFSET` clauses in SQL. ```scala Product.select.sortBy(_.price).map(_.name).drop(2).take(2) ``` ```sql SELECT product0.name AS res FROM product product0 ORDER BY product0.price LIMIT ? OFFSET ? ``` ```scala Seq("Face Mask", "Skate Board") ``` -------------------------------- ### FlatJoin.flatMapForGroupBy2 Scala Query Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Demonstrates using non-trivial queries in a for-comprehension which can result in subqueries being generated. This example uses groupBy and crossJoin. ```scala for { (name, dateOfBirth) <- Buyer.select.groupBy(_.name)(_.minBy(_.dateOfBirth)) (shippingInfoId, shippingDate) <- ShippingInfo.select .groupBy(_.id)(_.minBy(_.shippingDate)) .crossJoin() } yield (name, dateOfBirth, shippingInfoId, shippingDate) ``` ```sql SELECT subquery0.res_0 AS res_0, subquery0.res_1 AS res_1, subquery1.res_0 AS res_2, subquery1.res_1 AS res_3 FROM (SELECT buyer0.name AS res_0, MIN(buyer0.date_of_birth) AS res_1 FROM buyer buyer0 GROUP BY buyer0.name) subquery0 CROSS JOIN (SELECT shipping_info1.id AS res_0, MIN(shipping_info1.shipping_date) AS res_1 FROM shipping_info shipping_info1 GROUP BY shipping_info1.id) subquery1 ``` ```scala Seq( ("James Bond", LocalDate.parse("2001-02-03"), 1, LocalDate.parse("2010-02-03")), ("James Bond", LocalDate.parse("2001-02-03"), 2, LocalDate.parse("2012-04-05")), ("James Bond", LocalDate.parse("2001-02-03"), 3, LocalDate.parse("2012-05-06")), ("Li Haoyi", LocalDate.parse("1965-08-09"), 1, LocalDate.parse("2010-02-03")), ("Li Haoyi", LocalDate.parse("1965-08-09"), 2, LocalDate.parse("2012-04-05")), ("Li Haoyi", LocalDate.parse("1965-08-09"), 3, LocalDate.parse("2012-05-06")), ("叉烧包", LocalDate.parse("1923-11-12"), 1, LocalDate.parse("2010-02-03")), ("叉烧包", LocalDate.parse("1923-11-12"), 2, LocalDate.parse("2012-04-05")), ("叉烧包", LocalDate.parse("1923-11-12"), 3, LocalDate.parse("2012-05-06")) ) ``` -------------------------------- ### Join Patterns Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/00-index.md Demonstrates different ways to perform joins in ScalaSql, including inner and left joins. ```scala left.join(right)((l, r) => l.id === r.id) left.leftJoin(right)((l, r) => ...) // Implicit: for { a <- left; b <- right if ... } yield ... ``` -------------------------------- ### Table Definition Syntax Reference Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Reference for defining tables and columns using Scalasql's DSL. ```Scala case class Product(id: Int, name: String, price: BigDecimal) object products extends Table[Product](?) val id = col("id", int).primaryKey val name = col("name", varchar(255)) val price = col("price", bigDecimal) ``` -------------------------------- ### Raw SQL Reference Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/MANIFEST.md Reference for executing raw SQL queries. ```Scala // Interpolator sql"SELECT * FROM users WHERE id = ${userId}" // Direct execution db.runRaw("UPDATE settings SET value = 1 WHERE key = 'abc'") ``` -------------------------------- ### UnionAll Aggregate with Max/Min Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Shows how to combine results from two product selections using unionAll and then aggregate to find the maximum and minimum prices. Fields not selected in the outer query are eliminated before the unionAll operation. ```scala Product.select .map(p => (p.name.toLowerCase, p.price)) .unionAll(Product.select.map(p => (p.kebabCaseName.toLowerCase, p.price))) .aggregate(ps => (ps.maxBy(_._2), ps.minBy(_._2))) ``` ```sql SELECT MAX(subquery0.res_1) AS res_0, MIN(subquery0.res_1) AS res_1 FROM (SELECT product0.price AS res_1 FROM product product0 UNION ALL SELECT product0.price AS res_1 FROM product product0) subquery0 ``` ```scala (1000.0, 0.1) ``` -------------------------------- ### Implicit Queryable Resolution Example Source: https://github.com/com-lihaoyi/scalasql/blob/main/_autodocs/09-queryable-trait.md Shows how ScalaSql implicitly resolves Queryable instances for tables, expressions, and tuples during query construction. ```scala // This works because Queryable instances are automatically composed db.run( User.select .join(Post)((u, p) => u.id === p.userId) .map { case (user, post) => (user.id, user.name, post.title, post.views) } ) // Queryable finds instances for: // - User[Expr] (table) // - Post[Expr] (table) // - (User[Expr], Post[Expr]) (tuple) // - (Expr[Int], Expr[String], Expr[String], Expr[Int]) (projection) ``` -------------------------------- ### Values.basic usage Source: https://github.com/com-lihaoyi/scalasql/blob/main/docs/reference.md Demonstrates the basic usage of the `values` function to generate a SQL VALUES clause with a sequence of integers. ```scala db.values(Seq(1, 2, 3)) ``` ```sql VALUES (?), (?), (?) ``` ```scala Seq(1, 2, 3) ```