Skip to content

Commit

Permalink
More documentation of database schema methods
Browse files Browse the repository at this point in the history
  • Loading branch information
groue committed Oct 13, 2024
1 parent 4315030 commit c97f633
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 28 deletions.
129 changes: 108 additions & 21 deletions GRDB/Core/Database+Schema.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,15 @@ extension Database {

// MARK: - Database Schema

/// Returns the current schema version.
/// Returns the current schema version (`PRAGMA schema_version`).
///
/// For example:
///
/// ```swift
/// let version = try dbQueue.read { db in
/// try db.schemaVersion()
/// }
/// ```
///
/// Related SQLite documentation: <https://www.sqlite.org/pragma.html#pragma_schema_version>
public func schemaVersion() throws -> Int32 {
Expand Down Expand Up @@ -234,8 +242,19 @@ extension Database {

/// Returns whether a table exists
///
/// When `schemaName` is not specified, known schemas are iterated in
/// SQLite resolution order and the first matching result is returned.
/// When `schemaName` is not specified, the result is true if any known
/// schema contains the table.
///
/// For example:
///
/// ```swift
/// try dbQueue.read { db in
/// if try db.tableExists("player") { ... }
/// if try db.tableExists("player", in: "main") { ... }
/// if try db.tableExists("player", in: "temp") { ... }
/// if try db.tableExists("player", in: "attached") { ... }
/// }
/// ```
///
/// - throws: A ``DatabaseError`` whenever an SQLite error occurs, or
/// if the specified schema does not exist
Expand Down Expand Up @@ -278,8 +297,19 @@ extension Database {
/// Returns whether a view exists, in the main or temp schema, or in an
/// attached database.
///
/// When `schemaName` is not specified, known schemas are iterated in
/// SQLite resolution order and the first matching result is returned.
/// When `schemaName` is not specified, the result is true if any known
/// schema contains the table.
///
/// For example:
///
/// ```swift
/// try dbQueue.read { db in
/// if try db.viewExists("player") { ... }
/// if try db.viewExists("player", in: "main") { ... }
/// if try db.viewExists("player", in: "temp") { ... }
/// if try db.viewExists("player", in: "attached") { ... }
/// }
/// ```
///
/// - throws: A ``DatabaseError`` whenever an SQLite error occurs, or
/// if the specified schema does not exist
Expand All @@ -296,8 +326,19 @@ extension Database {
/// Returns whether a trigger exists, in the main or temp schema, or in an
/// attached database.
///
/// When `schemaName` is not specified, known schemas are iterated in
/// SQLite resolution order and the first matching result is returned.
/// When `schemaName` is not specified, the result is true if any known
/// schema contains the table.
///
/// For example:
///
/// ```swift
/// try dbQueue.read { db in
/// if try db.triggerExists("on_player_update") { ... }
/// if try db.triggerExists("on_player_update", in: "main") { ... }
/// if try db.triggerExists("on_player_update", in: "temp") { ... }
/// if try db.triggerExists("on_player_update", in: "attached") { ... }
/// }
/// ```
///
/// - throws: A ``DatabaseError`` whenever an SQLite error occurs, or
/// if the specified schema does not exist
Expand Down Expand Up @@ -340,6 +381,15 @@ extension Database {
/// table has no explicit primary key, the result is the hidden
/// "rowid" column.
///
/// For example:
///
/// ```swift
/// try dbQueue.read { db in
/// let primaryKey = try db.primaryKey("player")
/// print(primaryKey.columns)
/// }
/// ```
///
/// When `schemaName` is not specified, known schemas are iterated in
/// SQLite resolution order and the first matching result is returned.
///
Expand Down Expand Up @@ -529,14 +579,26 @@ extension Database {

/// The indexes on table named `tableName`.
///
/// For example:
///
/// ```swift
/// try dbQueue.read { db in
/// let indexes = db.indexes(in: "player")
/// for index in indexes {
/// print(index.columns)
/// }
/// }
/// ```
///
/// Only indexes on columns are returned. Indexes on expressions are
/// not returned.
///
/// SQLite does not define any index for INTEGER PRIMARY KEY columns: this
/// method does not return any index that represents the primary key.
/// SQLite does not define any index for INTEGER PRIMARY KEY columns:
/// this method does not return any index that represents the
/// primary key.
///
/// If you want to know if a set of columns uniquely identifies a row, because
/// the columns contain the primary key or a unique index, use
/// If you want to know if a set of columns uniquely identifies a row,
/// because the columns contain the primary key or a unique index, use
/// ``table(_:hasUniqueKey:)``.
///
/// When `schemaName` is not specified, known schemas are iterated in
Expand Down Expand Up @@ -617,16 +679,19 @@ extension Database {
/// For example:
///
/// ```swift
/// // One table with one primary key (id), and a unique index (a, b):
/// //
/// // > CREATE TABLE t(id INTEGER PRIMARY KEY, a, b, c);
/// // > CREATE UNIQUE INDEX i ON t(a, b);
/// try db.table("t", hasUniqueKey: ["id"]) // true
/// try db.table("t", hasUniqueKey: ["a", "b"]) // true
/// try db.table("t", hasUniqueKey: ["b", "a"]) // true
/// try db.table("t", hasUniqueKey: ["c"]) // false
/// try db.table("t", hasUniqueKey: ["id", "a"]) // true
/// try db.table("t", hasUniqueKey: ["id", "a", "b", "c"]) // true
/// try dbQueue.read { db in
/// // One table with one primary key (id)
/// // and a unique index (a, b):
/// //
/// // > CREATE TABLE t(id INTEGER PRIMARY KEY, a, b, c);
/// // > CREATE UNIQUE INDEX i ON t(a, b);
/// try db.table("t", hasUniqueKey: ["id"]) // true
/// try db.table("t", hasUniqueKey: ["a", "b"]) // true
/// try db.table("t", hasUniqueKey: ["b", "a"]) // true
/// try db.table("t", hasUniqueKey: ["c"]) // false
/// try db.table("t", hasUniqueKey: ["id", "a"]) // true
/// try db.table("t", hasUniqueKey: ["id", "a", "b", "c"]) // true
/// }
/// ```
public func table(
_ tableName: String,
Expand All @@ -640,6 +705,17 @@ extension Database {
/// When `schemaName` is not specified, known schemas are iterated in
/// SQLite resolution order and the first matching result is returned.
///
/// For example:
///
/// ```swift
/// try dbQueue.read { db in
/// let foreignKeys = try db.foreignKeys(in: "player")
/// for foreignKey in foreignKeys {
/// print(foreignKey.destinationTable)
/// }
/// }
/// ```
///
/// - throws: A ``DatabaseError`` whenever an SQLite error occurs, if
/// the specified schema does not exist, or if no such table or view
/// with this name exists in the main or temp schema, or in an attached
Expand Down Expand Up @@ -861,6 +937,17 @@ extension Database {
/// When `schemaName` is not specified, known schemas are iterated in
/// SQLite resolution order and the first matching result is returned.
///
/// For example:
///
/// ```swift
/// try dbQueue.read { db in
/// let columns = try db.columns(in: "player")
/// for column in columns {
/// print(column.name)
/// }
/// }
/// ```
///
/// - throws: A ``DatabaseError`` whenever an SQLite error occurs, if
/// the specified schema does not exist,or if no such table or view
/// with this name exists in the main or temp schema, or in an attached
Expand Down
26 changes: 19 additions & 7 deletions GRDB/Documentation.docc/DatabaseSchemaIntrospection.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,31 @@ Get information about schema objects such as tables, columns, indexes, foreign k

## Topics

### Querying the Database Schema
### Querying the Schema Version

- ``Database/schemaVersion()``

### Existence Checks

- ``Database/tableExists(_:in:)``
- ``Database/triggerExists(_:in:)``
- ``Database/viewExists(_:in:)``

### Table Structure

- ``Database/columns(in:in:)``
- ``Database/foreignKeys(on:in:)``
- ``Database/indexes(on:in:)``
- ``Database/isGRDBInternalTable(_:)``
- ``Database/isSQLiteInternalTable(_:)``
- ``Database/primaryKey(_:in:)``
- ``Database/schemaVersion()``
- ``Database/table(_:hasUniqueKey:)``
- ``Database/tableExists(_:in:)``
- ``Database/triggerExists(_:in:)``
- ``Database/viewExists(_:in:)``

### Reserved Tables

- ``Database/isGRDBInternalTable(_:)``
- ``Database/isSQLiteInternalTable(_:)``

### Supporting Types

- ``ColumnInfo``
- ``ForeignKeyInfo``
- ``IndexInfo``
Expand Down

0 comments on commit c97f633

Please sign in to comment.