or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

database-io.mddatabase-profiles.mdindex.mdplain-sql.mdqueries.mdtable-definitions.mdtype-mappings.md

table-definitions.mddocs/

0

# Table Definitions

1

2

Define database tables with strongly-typed columns, constraints, and schema operations in Slick.

3

4

## Capabilities

5

6

### Table Classes

7

8

Define database tables by extending the `Table` class with column definitions and table metadata.

9

10

```scala { .api }

11

/**

12

* Base class for database table definitions

13

* @param tag Table tag for identification

14

* @param tableName Name of the database table

15

*/

16

abstract class AbstractTable[T](tag: Tag, tableName: String)

17

18

/**

19

* Concrete table class for defining database tables

20

* @param tag Table tag for identification

21

* @param tableName Name of the database table

22

*/

23

class Table[T](tag: Tag, tableName: String) extends AbstractTable[T] {

24

/** Default projection - defines which columns make up the table's row type */

25

def * : ProvenShape[T]

26

}

27

28

/**

29

* Table tag for identifying table instances

30

*/

31

final class Tag(val taggedAs: Any)

32

```

33

34

**Usage Examples:**

35

36

```scala

37

// Simple table definition

38

class Users(tag: Tag) extends Table[(Int, String)](tag, "users") {

39

def id = column[Int]("id", O.PrimaryKey, O.AutoInc)

40

def name = column[String]("name")

41

def * = (id, name)

42

}

43

44

// Table with case class mapping

45

final case class Coffee(name: String, price: Double)

46

47

class Coffees(tag: Tag) extends Table[Coffee](tag, "coffees") {

48

def name = column[String]("name")

49

def price = column[Double]("price")

50

def * = (name, price).mapTo[Coffee]

51

}

52

```

53

54

### Column Definitions

55

56

Define typed columns with constraints and options.

57

58

```scala { .api }

59

/**

60

* Define a table column with type T

61

* @param name Column name in the database

62

* @param options Column options like primary key, auto increment, etc.

63

*/

64

def column[T](name: String, options: ColumnOption[T]*): Rep[T]

65

66

/**

67

* Represents a column or expression that can be used in queries

68

*/

69

trait Rep[T] {

70

/** Column equality comparison */

71

def ===[P2, R](e: P2)(implicit om: o.=:=[Rep[P2], Rep[Option[T]]], sh: Shape[_ <: FlatShapeLevel, Rep[P2], T, Rep[P2]]): Rep[Boolean]

72

73

/** Column inequality comparison */

74

def =!=[P2, R](e: P2)(implicit om: o.=:=[Rep[P2], Rep[Option[T]]], sh: Shape[_ <: FlatShapeLevel, Rep[P2], T, Rep[P2]]): Rep[Boolean]

75

}

76

```

77

78

### Column Options

79

80

Specify column constraints and behavior using column options.

81

82

```scala { .api }

83

/**

84

* Column options for specifying constraints and behavior

85

*/

86

sealed trait ColumnOption[+T]

87

88

object O {

89

/** Primary key constraint */

90

case object PrimaryKey extends ColumnOption[Nothing]

91

92

/** Auto-increment column */

93

case object AutoInc extends ColumnOption[Nothing]

94

95

/** Unique constraint */

96

case object Unique extends ColumnOption[Nothing]

97

98

/** Not null constraint */

99

case object NotNull extends ColumnOption[Nothing]

100

101

/** Column length specification */

102

case class Length(length: Int) extends ColumnOption[Nothing]

103

104

/** Default value for column */

105

case class Default[T](defaultValue: T) extends ColumnOption[T]

106

107

/** Foreign key constraint */

108

case class ForeignKey[T](name: String, sourceColumns: Any, targetTableQuery: Any, targetColumns: Any, onUpdate: ForeignKeyAction, onDelete: ForeignKeyAction) extends ColumnOption[T]

109

}

110

```

111

112

**Usage Examples:**

113

114

```scala

115

class Products(tag: Tag) extends Table[Product](tag, "products") {

116

def id = column[Int]("id", O.PrimaryKey, O.AutoInc)

117

def name = column[String]("name", O.Length(100))

118

def description = column[Option[String]]("description")

119

def price = column[BigDecimal]("price")

120

def categoryId = column[Int]("category_id")

121

def isActive = column[Boolean]("is_active", O.Default(true))

122

def createdAt = column[Timestamp]("created_at", O.Default(new Timestamp(System.currentTimeMillis())))

123

124

def * = (id, name, description, price, categoryId, isActive, createdAt).mapTo[Product]

125

}

126

```

127

128

### TableQuery

129

130

Access and query database tables using TableQuery objects.

131

132

```scala { .api }

133

/**

134

* Represents a database table that can be queried

135

*/

136

abstract class TableQuery[E <: AbstractTable[_]] extends Query[E, E#TableElementType, Seq] {

137

/** Get the table's schema DDL */

138

def schema: SchemaDescription

139

140

/** Insert a single row */

141

def += (value: E#TableElementType): ProfileAction[Int, NoStream, Write]

142

143

/** Insert multiple rows */

144

def ++= (values: Iterable[E#TableElementType]): ProfileAction[Int, NoStream, Write]

145

146

/** Insert or update a row */

147

def insertOrUpdate(value: E#TableElementType): ProfileAction[Int, NoStream, Write]

148

}

149

150

object TableQuery {

151

/**

152

* Create a TableQuery for the given table class

153

*/

154

def apply[E <: AbstractTable[_]](cons: Tag => E): TableQuery[E]

155

}

156

```

157

158

**Usage Examples:**

159

160

```scala

161

// Create TableQuery instances

162

val users = TableQuery[Users]

163

val coffees = TableQuery[Coffees]

164

val products = TableQuery[Products]

165

166

// Insert operations

167

val insertUser = users += (0, "Alice")

168

val insertCoffee = coffees += Coffee("Latte", 2.50)

169

val insertMultiple = coffees ++= Seq(

170

Coffee("Espresso", 1.80),

171

Coffee("Cappuccino", 2.20)

172

)

173

```

174

175

### Schema Operations

176

177

Create, drop, and manage database schemas.

178

179

```scala { .api }

180

/**

181

* Schema description for DDL operations

182

*/

183

trait SchemaDescription {

184

/** Create the schema if it doesn't exist */

185

def createIfNotExists: ProfileAction[Unit, NoStream, Write]

186

187

/** Create the schema */

188

def create: ProfileAction[Unit, NoStream, Write]

189

190

/** Drop the schema if it exists */

191

def dropIfExists: ProfileAction[Unit, NoStream, Write]

192

193

/** Drop the schema */

194

def drop: ProfileAction[Unit, NoStream, Write]

195

196

/** Truncate all tables in the schema */

197

def truncate: ProfileAction[Unit, NoStream, Write]

198

}

199

```

200

201

**Usage Examples:**

202

203

```scala

204

// Create schema for single table

205

val createUsersSchema = users.schema.create

206

207

// Create schema for multiple tables

208

val schema = users.schema ++ coffees.schema ++ products.schema

209

val createAllSchema = schema.create

210

211

// Schema management

212

val setupDb = DBIO.seq(

213

schema.createIfNotExists,

214

users += (0, "admin"),

215

coffees ++= Seq(

216

Coffee("Americano", 2.00),

217

Coffee("Mocha", 3.50)

218

)

219

)

220

```

221

222

### Constraints and Indexes

223

224

Define primary keys, foreign keys, and indexes on tables.

225

226

```scala { .api }

227

/**

228

* Primary key definition

229

*/

230

def primaryKey(name: String, columns: Any): PrimaryKey

231

232

/**

233

* Foreign key definition

234

*/

235

def foreignKey(name: String, sourceColumns: Any, targetTableQuery: Any)(targetColumns: Any => Any): ForeignKeyQuery[_, _]

236

237

/**

238

* Index definition

239

*/

240

def index(name: String, columns: Any, unique: Boolean = false): Index

241

```

242

243

**Usage Examples:**

244

245

```scala

246

class Orders(tag: Tag) extends Table[Order](tag, "orders") {

247

def id = column[Int]("id", O.AutoInc)

248

def userId = column[Int]("user_id")

249

def productId = column[Int]("product_id")

250

def quantity = column[Int]("quantity")

251

def orderDate = column[Date]("order_date")

252

253

def * = (id, userId, productId, quantity, orderDate).mapTo[Order]

254

255

// Composite primary key

256

def pk = primaryKey("pk_orders", (userId, productId, orderDate))

257

258

// Foreign key constraints

259

def userFk = foreignKey("fk_order_user", userId, users)(_.id, onUpdate=ForeignKeyAction.Restrict, onDelete=ForeignKeyAction.Cascade)

260

def productFk = foreignKey("fk_order_product", productId, products)(_.id)

261

262

// Indexes

263

def userIndex = index("idx_order_user", userId)

264

def dateIndex = index("idx_order_date", orderDate)

265

def uniqueUserProductIndex = index("idx_unique_user_product", (userId, productId), unique = true)

266

}

267

```

268

269

### Sequences

270

271

Define and use database sequences for generating values.

272

273

```scala { .api }

274

/**

275

* Database sequence definition

276

*/

277

class Sequence[T](name: String, start: Long = 1, inc: Long = 1, min: Option[Long] = None, max: Option[Long] = None, cycle: Boolean = false)(implicit tpe: ColumnType[Long], integral: Integral[T])

278

279

/**

280

* Sequence operations

281

*/

282

trait SequenceOps {

283

/** Get the next value from the sequence */

284

def nextValue: Rep[T]

285

286

/** Get the current value of the sequence */

287

def currValue: Rep[T]

288

}

289

```

290

291

**Usage Examples:**

292

293

```scala

294

// Define sequences

295

val userIdSeq = Sequence[Long]("user_id_seq")

296

val orderIdSeq = Sequence[Long]("order_id_seq", start = 1000, inc = 1)

297

298

class UsersWithSequence(tag: Tag) extends Table[User](tag, "users") {

299

def id = column[Long]("id", O.Default(userIdSeq.nextValue))

300

def name = column[String]("name")

301

def * = (id, name).mapTo[User]

302

}

303

304

// Use sequence in queries

305

val nextUserId = userIdSeq.nextValue

306

val insertWithSequence = users += User(0L, "Bob") // ID will be auto-generated

307

```

308

309

## Types

310

311

```scala { .api }

312

trait ColumnOption[+T]

313

case class Sequence[T](name: String, start: Long, inc: Long, min: Option[Long], max: Option[Long], cycle: Boolean)

314

trait SchemaDescription

315

case class PrimaryKey(name: String, columns: IndexedSeq[Node])

316

case class ForeignKey(name: String, sourceTable: String, sourceColumns: Seq[String], targetTable: String, targetColumns: Seq[String], onUpdate: ForeignKeyAction, onDelete: ForeignKeyAction)

317

case class Index(name: String, table: String, on: Seq[(String, SortDirection)], unique: Boolean)

318

319

trait ForeignKeyAction

320

object ForeignKeyAction {

321

case object Cascade extends ForeignKeyAction

322

case object Restrict extends ForeignKeyAction

323

case object NoAction extends ForeignKeyAction

324

case object SetNull extends ForeignKeyAction

325

case object SetDefault extends ForeignKeyAction

326

}

327

```