### Example: MySQLData from Decimal Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Demonstrates creating a MySQLData instance from a Swift Decimal. ```swift MySQLData(decimal: Decimal(string: "123.45")!) ``` -------------------------------- ### Example: MySQLData from Date Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Demonstrates creating a MySQLData instance from a Swift Date. ```swift MySQLData(date: Date()) ``` -------------------------------- ### Example: MySQLTime Initialization from String Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLTime.md Demonstrates parsing a MySQLTime from a string, including examples with and without microseconds. The initializer returns nil for invalid formats. ```swift if let time = MySQLTime("2024-05-24 14:30:45") { print("Parsed: \(time)") } if let time = MySQLTime("2024-05-24 14:30:45.123456") { print("With microseconds: \(time)") } ``` -------------------------------- ### Example: MySQLData from MySQLTime Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Demonstrates creating a MySQLData instance from a MySQLTime object. ```swift MySQLData(time: MySQLTime(year: 2024, month: 5, day: 24)) ``` -------------------------------- ### Example: MySQLData from Int Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Demonstrates creating a MySQLData instance from a 64-bit Swift Int. ```swift MySQLData(int: 42) ``` -------------------------------- ### Example: MySQLData from String Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Demonstrates creating a MySQLData instance from a Swift String. ```swift MySQLData(string: "hello") ``` -------------------------------- ### Example: MySQLData from Bool Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Demonstrates creating a MySQLData instance from a Swift Bool. ```swift MySQLData(bool: true) ``` -------------------------------- ### Example: MySQLData from UUID Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Demonstrates creating a MySQLData instance from a Swift UUID. ```swift MySQLData(uuid: UUID()) ``` -------------------------------- ### Example: MySQLData from Float Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Demonstrates creating a MySQLData instance from a Swift Float. ```swift MySQLData(float: 1.5) ``` -------------------------------- ### Example: MySQLData from Double Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Demonstrates creating a MySQLData instance from a Swift Double. ```swift MySQLData(double: 3.14159) ``` -------------------------------- ### Example: MySQLTime Initialization from Date Object Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLTime.md Shows how to create a MySQLTime instance directly from a Swift Date object. ```swift let now = Date() let mysqlTime = MySQLTime(date: now) ``` -------------------------------- ### Custom Implementation Example Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLDataConvertible.md Demonstrates how to implement MySQLDataConvertible for custom Swift types, using UserId as an example. ```APIDOC ## Custom Implementations You can implement `MySQLDataConvertible` for custom types: ```swift struct UserId: MySQLDataConvertible { let value: Int64 init?(mysqlData: MySQLData) { guard let value = mysqlData.int64 else { return nil } self.value = value } var mysqlData: MySQLData? { .init(int: Int(value)) } } // Now you can use UserId directly in queries let userId = UserId(value: 42) try await db.query( "SELECT * FROM users WHERE id = ?", [userId.mysqlData!] ).get() ``` ``` -------------------------------- ### Install OpenSSL Development Libraries on Linux Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/configuration.md Provides the command to install OpenSSL development libraries on Linux (Ubuntu 20.04+), which is necessary for TLS support. ```bash apt-get install libssl-dev ``` -------------------------------- ### Example: MySQLTime Initialization Variations Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLTime.md Illustrates different ways to initialize MySQLTime: with date components, with time components, and with a full datetime including microseconds. ```swift // Create a date let date = MySQLTime(year: 2024, month: 5, day: 24) // Create a time let time = MySQLTime(hour: 14, minute: 30, second: 45) // Create a datetime let datetime = MySQLTime( year: 2024, month: 5, day: 24, hour: 14, minute: 30, second: 45, microsecond: 123456 ) ``` -------------------------------- ### Performing MySQL Transactions Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/INDEX.md Provides an example of how to execute a series of SQL statements within a transaction, ensuring atomicity by starting, committing, or rolling back the transaction. ```swift try await db.simpleQuery("START TRANSACTION").get() try await db.query("INSERT INTO accounts (name) VALUES (?)", params).get() try await db.query("UPDATE balances SET amount = ?", params).get() try await db.simpleQuery("COMMIT").get() ``` -------------------------------- ### Example: Creating and Storing Current Time Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLTime.md Demonstrates how to create a MySQLTime from the current Date and store it in a MySQL database using parameterized queries. ```swift import MySQLNIO let db: any MySQLDatabase = ... let now = Date() let mysqlTime = MySQLTime(date: now) try await db.query( "INSERT INTO events (timestamp) VALUES (?)", [mysqlTime.mysqlData!] ).get() ``` -------------------------------- ### Example: MySQLData from JSON Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Illustrates creating MySQLData from a JSON-encodable struct. The struct must conform to the Encodable protocol. ```swift struct Person: Encodable { let name: String } let data = try MySQLData(json: Person(name: "Alice")) ``` -------------------------------- ### Error Handling Example Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/README.md Demonstrates how to catch and handle specific MySQL errors. ```APIDOC ## Error Handling ### Description Provides an example of how to catch and handle `MySQLError` exceptions, including specific error cases like duplicate entries. ### Request Example ```swift do { try await db.query("INSERT INTO users (id, name) VALUES (?, ?)", [MySQLData(int: 1), MySQLData(string: "Alice")]).get() } catch let error as MySQLError { switch error { case .duplicateEntry(let msg): print("Error: Duplicate entry found - \(msg)") case .connectionClosed: print("Error: Connection was closed unexpectedly.") default: print("An unexpected MySQL error occurred: \(error)") } } catch { print("A non-MySQL error occurred: \(error)") } ``` ``` -------------------------------- ### String Conversion Example Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLDataConvertible.md Demonstrates how to use String with MySQLDataConvertible for direct string parameterization in queries. ```APIDOC ### String ```swift extension String: MySQLDataConvertible ``` Enables direct string parameterization. **Example:** ```swift let name = "Alice" try await db.query("SELECT * FROM users WHERE name = ?", [name.mysqlData!]).get() ``` ``` -------------------------------- ### Float Conversion Example Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLDataConvertible.md Illustrates Float conformance to MySQLDataConvertible, converting to MySQL FLOAT format. ```APIDOC ### Float ```swift extension Float: MySQLDataConvertible ``` Converts to MySQL FLOAT format. **Example:** ```swift let rating: Float = 4.5 try await db.query("INSERT INTO reviews (rating) VALUES (?)", [rating.mysqlData!]).get() ``` ``` -------------------------------- ### Bool Conversion Example Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLDataConvertible.md Shows how Bool conforms to MySQLDataConvertible, converting to MySQL TINY(1) format. ```APIDOC ### Bool ```swift extension Bool: MySQLDataConvertible ``` Converts to MySQL TINY(1) format. **Example:** ```swift let isActive = true try await db.query("SELECT * FROM users WHERE active = ?", [isActive.mysqlData!]).get() ``` ``` -------------------------------- ### Example: MySQLTime Initialization from MySQLData Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLTime.md Illustrates creating a MySQLTime instance from MySQLData. The initializer returns nil if the data is not valid time information. ```swift let data: MySQLData = ... if let time = MySQLTime(mysqlData: data) { print("Time: \(time)") } ``` -------------------------------- ### Simplified Parameter Binding Example Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLDataConvertible.md Shows a helper extension for Array to simplify parameter binding using MySQLDataConvertible values. ```APIDOC ## Simplified Parameter Binding With `MySQLDataConvertible`, you can create helper extensions to simplify parameter arrays: ```swift extension Array { init(_ values: MySQLDataConvertible...) { self = values.compactMap { $0.mysqlData } } } // Then use like: let rows = try await db.query( "SELECT * FROM users WHERE name = ? AND active = ?", [MySQLData(string: "Alice"), MySQLData(bool: true)] ).get() ``` ``` -------------------------------- ### Double Conversion Example Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLDataConvertible.md Shows Double conformance to MySQLDataConvertible, converting to MySQL DOUBLE format. ```APIDOC ### Double ```swift extension Double: MySQLDataConvertible ``` Converts to MySQL DOUBLE format. **Example:** ```swift let price = 19.99 try await db.query("INSERT INTO items (price) VALUES (?)", [price.mysqlData!]).get() ``` ``` -------------------------------- ### Example: Converting MySQLTime to Date Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLTime.md Shows how to convert a MySQLTime instance back to a Swift Date object. This conversion requires year, month, and day to be set. ```swift let time = MySQLTime(year: 2024, month: 5, day: 24, hour: 14, minute: 30, second: 0) if let date = time.date { print("Date: \(date)") } ``` -------------------------------- ### MySQLData Integer Conversion Example Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Demonstrates how to retrieve an Int64 value from MySQLData. Ensure the data is compatible before attempting conversion. ```swift let data: MySQLData = ... if let value = data.int64 { print("Value: \(value)") } ``` -------------------------------- ### Decimal Conversion Example Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLDataConvertible.md Shows Decimal conformance to MySQLDataConvertible, converting to MySQL NEWDECIMAL format while preserving precision. ```APIDOC ### Decimal ```swift extension Decimal: MySQLDataConvertible ``` Converts to MySQL NEWDECIMAL format, preserving precision. **Example:** ```swift let amount = Decimal(string: "123.45")! try await db.query("INSERT INTO transactions (amount) VALUES (?)", [amount.mysqlData!]).get() ``` ``` -------------------------------- ### Example: MySQLData Null Value Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Demonstrates how to represent a NULL value using the static `null` property of MySQLData. ```swift MySQLData.null ``` -------------------------------- ### UUID Conversion Example Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLDataConvertible.md Demonstrates UUID conformance to MySQLDataConvertible, converting to MySQL BLOB format (16 bytes). ```APIDOC ### UUID ```swift extension UUID: MySQLDataConvertible ``` Converts to MySQL BLOB format (16 bytes). **Example:** ```swift let id = UUID() try await db.query("INSERT INTO records (id) VALUES (?)", [id.mysqlData!]).get() ``` ``` -------------------------------- ### Date Conversion Example Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLDataConvertible.md Illustrates Date conformance to MySQLDataConvertible, converting to MySQL DATETIME format using UTC timezone. ```APIDOC ### Date ```swift extension Date: MySQLDataConvertible ``` Converts to MySQL DATETIME format using UTC timezone. **Example:** ```swift let now = Date() try await db.query("INSERT INTO events (timestamp) VALUES (?)", [now.mysqlData!]).get() ``` ``` -------------------------------- ### MySQLData JSON Decoding Example Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Demonstrates decoding a JSON string from MySQLData into a custom Decodable struct. Ensure the JSON structure matches the struct. ```swift struct Config: Decodable { let timeout: Int let retries: Int } let data: MySQLData = ... let config = try data.json(as: Config.self) ``` -------------------------------- ### Custom MySQLDataConvertible Implementation Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLDataConvertible.md Provides an example of implementing `MySQLDataConvertible` for a custom `UserId` struct, enabling its use in queries. ```swift struct UserId: MySQLDataConvertible { let value: Int64 init?(mysqlData: MySQLData) { guard let value = mysqlData.int64 else { return nil } self.value = value } var mysqlData: MySQLData? { .init(int: Int(value)) } } // Now you can use UserId directly in queries let userId = UserId(value: 42) try await db.query( "SELECT * FROM users WHERE id = ?", [userId.mysqlData!] ).get() ``` -------------------------------- ### Handle MySQL Errors Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/INDEX.md Provides examples of catching and handling specific MySQL errors, including server errors and duplicate entry errors, as well as general MySQL errors. ```swift do { try await db.query("SELECT * FROM invalid_table").get() } catch let error as MySQLError, case .server(let packet) = error { print("Error \(packet.errorCode): \(packet.errorMessage)") } catch let error as MySQLError, case .duplicateEntry(let msg) = error { print("Duplicate entry: \(msg)") } catch let error as MySQLError { print("MySQL error: \(error.message)") } ``` -------------------------------- ### Comprehensive MySQL Error Handling Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/INDEX.md Provides an example of how to handle various MySQL errors using a switch statement on the caught MySQLError. This includes specific cases like duplicate entries and server errors. ```swift do { let rows = try await db.query(sql, params).get() } catch let error as MySQLError { switch error { case .duplicateEntry(let msg): print("Duplicate: \(msg)") case .invalidSyntax(let msg): print("SQL error: \(msg)") case .server(let packet): print("Server error \(packet.errorCode)") case .closed: print("Connection closed") default: print("MySQL error: \(error.message)") } } ``` -------------------------------- ### Execute Simple Query and Get Rows Source: https://github.com/vapor/mysql-nio/blob/main/README.md Executes a simple SQL query as a string and retrieves all resulting rows. Values must be manually escaped. Suitable for schema or transactional queries. ```swift let rows = try await db.simpleQuery("SELECT @@version").get() print(rows) // [["@@version": "8.x.x"]] ``` -------------------------------- ### Execute Parameterized Query and Get Rows Source: https://github.com/vapor/mysql-nio/blob/main/README.md Executes a parameterized SQL query with bound parameters and retrieves all resulting rows. Uses efficient binary format for data transfer. Ideal for selecting, inserting, and updating data. ```swift let rows = try await db.query("SELECT * FROM planets WHERE name = ?", ["Earth"]).get() print(rows) // [["id": 42, "name": "Earth"]] ``` -------------------------------- ### Create a MySQL Connection Source: https://github.com/vapor/mysql-nio/blob/main/README.md Demonstrates how to establish a connection to a MySQL server using MySQLNIO. Requires an EventLoop, host, port, username, database, and password. TLS configuration and server hostname can be optionally provided. ```swift import MySQLNIO let eventLoop: any EventLoop = ... let conn = try await MySQLConnection( to: .makeAddressResolvingHost("my.mysql.server", port: 3306), username: "test_username", database: "test_database", password: "test_password", on: eventLoop ).get() ``` -------------------------------- ### Full MySQL Connection Configuration Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/INDEX.md Illustrates how to establish a MySQL connection with detailed configuration, including TLS settings, a custom logger, and specifying the server address and credentials. ```swift import NIOSSL import Logging var tlsConfig = TLSConfiguration.makeClientConfiguration() var logger = Logger(label: "app.mysql") logger.logLevel = .debug let conn = try await MySQLConnection.connect( to: .makeAddressResolvingHost("db.example.com", port: 3306), username: "appuser", database: "production", password: "secret", tlsConfiguration: tlsConfig, serverHostname: "db.example.com", logger: logger, on: eventLoop ).get() ``` -------------------------------- ### MySQLTime Initialization Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLTime.md Demonstrates how to create MySQLTime instances for date-only, time-only, and full datetime values, including microseconds. ```APIDOC ## MySQLTime Initialization ### Description Provides examples of initializing `MySQLTime` objects with different combinations of date and time components. ### Date-Only ```swift let dateOnly = MySQLTime(year: 2024, month: 5, day: 24) ``` ### Time-Only ```swift let timeOnly = MySQLTime(hour: 14, minute: 30, second: 45) ``` ### Full Datetime with Microseconds ```swift let fullDateTime = MySQLTime( year: 2024, month: 5, day: 24, hour: 14, minute: 30, second: 45, microsecond: 123456 ) ``` ``` -------------------------------- ### Import MySQLNIO Source: https://github.com/vapor/mysql-nio/blob/main/README.md Import the MySQLNIO library to begin interacting with MySQL databases. Assumes a database connection is already established. ```swift import MySQLNIO let db: any MySQLDatabase = ... // now we can use client to do queries ``` -------------------------------- ### Configure MySQL Connection Using Environment Variables Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/configuration.md Illustrates how to programmatically configure MySQL connection parameters by reading from environment variables. Provides default values if variables are not set. ```swift let mysqlHost = Environment.get("MYSQL_HOST") ?? "localhost" let mysqlUser = Environment.get("MYSQL_USER") ?? "root" let mysqlPassword = Environment.get("MYSQL_PASSWORD") let mysqlDatabase = Environment.get("MYSQL_DATABASE") ?? "myapp" let mysqlPort = Int(Environment.get("MYSQL_PORT") ?? "3306") ?? 3306 let socketAddr = SocketAddress.makeAddressResolvingHost(mysqlHost, port: mysqlPort) let conn = try await MySQLConnection.connect( to: socketAddr, username: mysqlUser, database: mysqlDatabase, password: mysqlPassword, on: eventLoop ).get() ``` -------------------------------- ### MySQLTime Initialization Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLTime.md Demonstrates the various ways to initialize a MySQLTime object, including by individual components, from a Swift Date, and by parsing a string. ```APIDOC ## init(year:month:day:hour:minute:second:microsecond:) ### Description Creates a `MySQLTime` with optional date and time components. ### Method `init(year:month:day:hour:minute:second:microsecond:)` ### Parameters #### Path Parameters - **year** (`UInt16?`) - Optional - Year (e.g., 2024) - **month** (`UInt16?`) - Optional - Month 1-12 - **day** (`UInt16?`) - Optional - Day 1-31 - **hour** (`UInt16?`) - Optional - Hour 0-23 - **minute** (`UInt16?`) - Optional - Minute 0-59 - **second** (`UInt16?`) - Optional - Second 0-59 - **microsecond** (`UInt32?`) - Optional - Microseconds 0-999999 ### Request Example ```swift // Create a date let date = MySQLTime(year: 2024, month: 5, day: 24) // Create a time let time = MySQLTime(hour: 14, minute: 30, second: 45) // Create a datetime let datetime = MySQLTime( year: 2024, month: 5, day: 24, hour: 14, minute: 30, second: 45, microsecond: 123456 ) ``` ## init(date:) ### Description Creates a `MySQLTime` from a Swift `Date` object, using UTC timezone. ### Method `init(date: Date)` ### Parameters #### Path Parameters - **date** (`Date`) - Required - Swift Date object ### Request Example ```swift let now = Date() let mysqlTime = MySQLTime(date: now) ``` ## init(_:) ### Description Parses a `MySQLTime` from a string in format "yyyy-MM-dd hh:mm:ss" or variations with microseconds. Returns `nil` if the string format is invalid. ### Method `init?(_ string: String)` ### Parameters #### Path Parameters - **string** (`String`) - Required - Datetime string to parse ### Request Example ```swift if let time = MySQLTime("2024-05-24 14:30:45") { print("Parsed: \(time)") } if let time = MySQLTime("2024-05-24 14:30:45.123456") { print("With microseconds: \(time)") } ``` ## init(mysqlData:) ### Description Constructs a `MySQLTime` from `MySQLData`, implementing the `MySQLDataConvertible` protocol. Returns `nil` if the data doesn't contain valid time information. ### Method `init?(mysqlData: MySQLData)` ### Parameters #### Path Parameters - **mysqlData** (`MySQLData`) - Required - Data to convert ### Request Example ```swift let data: MySQLData = ... if let time = MySQLTime(mysqlData: data) { print("Time: \(time)") } ``` ``` -------------------------------- ### Execute MySQL Queries with Options Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/configuration.md Demonstrates different ways to execute queries, including parameterized queries, simple queries, and queries with row and metadata callbacks for processing results. ```swift let db: any MySQLDatabase = conn // Parameterized query let rows = try await db.query( "SELECT * FROM users WHERE age > ?", [MySQLData(int: 18)] ).get() // Simple query let version = try await db.simpleQuery("SELECT @@version").get() // With callbacks try await db.query( "SELECT * FROM large_table", onRow: { row in // Process each row as it arrives print(row) }, onMetadata: { metadata in print("Affected rows: \(metadata.affectedRows)") } ).get() ``` -------------------------------- ### Connect to MySQL Server Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLConnection.md Establishes a connection to a MySQL server using provided credentials and address. TLS is enabled by default. Ensure you have a running MySQL instance and the necessary credentials. ```swift import MySQLNIO import NIO let eventLoop: EventLoop = ... let conn = try await MySQLConnection.connect( to: .makeAddressResolvingHost("localhost", port: 3306), username: "root", database: "myapp", password: "password", on: eventLoop ).get() defer { try? conn.close().wait() } ``` -------------------------------- ### init(mysqlData:) Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLDataConvertible.md Initializes a value from MySQLData. Returns nil if the conversion fails. ```APIDOC ## Requirements ### `init(mysqlData:)` ```swift init?(mysqlData: MySQLData) ``` Initializes a value from `MySQLData`. Returns `nil` if conversion fails. ``` -------------------------------- ### Add MySQLNIO to Package.swift Source: https://github.com/vapor/mysql-nio/blob/main/README.md Use standard SwiftPM syntax to include MySQLNIO as a dependency in your Package.swift file. ```swift .package(url: "https://github.com/vapor/mysql-nio.git", from: "1.0.0") ``` -------------------------------- ### Create MySQL Connection Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/README.md Establishes a connection to a MySQL database. Ensure you have the correct host, port, username, database, password, and an event loop configured. ```swift try await MySQLConnection.connect( to: .makeAddressResolvingHost("localhost", port: 3306), username: "user", database: "db", password: "pass", on: eventLoop ).get() ``` -------------------------------- ### Create MySQLTime Instances Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLTime.md Demonstrates creating `MySQLTime` objects for date-only, time-only, and full datetime values, including microseconds. Useful for constructing query parameters. ```swift // Date only (no time) let dateOnly = MySQLTime(year: 2024, month: 5, day: 24) // Time only (no date) let timeOnly = MySQLTime(hour: 14, minute: 30, second: 45) // Full datetime with microseconds let fullDateTime = MySQLTime( year: 2024, month: 5, day: 24, hour: 14, minute: 30, second: 45, microsecond: 123456 ) ``` -------------------------------- ### Getting Last Insert ID from INSERT Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-QueryMetadata.md Captures the last insert ID from an INSERT operation into a variable for later use. ```swift var lastId: UInt64? = nil try await db.query( "INSERT INTO users (name) VALUES (?)", [MySQLData(string: "Bob")], onMetadata: { metadata in lastId = metadata.lastInsertID } ).get() if let id = lastId { print("Created user \(id)") } else { print("Failed to get last insert ID") } ``` -------------------------------- ### Initialize MySQLTime with Components Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLTime.md Creates a MySQLTime instance using optional year, month, day, hour, minute, second, and microsecond components. All parameters default to nil. ```swift public init( year: UInt16? = nil, month: UInt16? = nil, day: UInt16? = nil, hour: UInt16? = nil, minute: UInt16? = nil, second: UInt16? = nil, microsecond: UInt32? = nil ) ``` -------------------------------- ### Getting Metadata with Row Callback Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-QueryMetadata.md Retrieves query metadata, including affected rows and last insert ID, alongside processing individual rows. ```swift let db: any MySQLDatabase = ... var rowCount = 0 try await db.query( "SELECT * FROM users", onRow: { row in rowCount += 1 print(row) }, onMetadata: { metadata in print("Query affected \(metadata.affectedRows) rows") print("Inserted ID: \(metadata.lastInsertID ?? 0)") } ).get() ``` -------------------------------- ### Getting Metadata Without Row Callback Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-QueryMetadata.md Executes an INSERT query and retrieves the last insert ID using the onMetadata callback, without processing rows. ```swift let db: any MySQLDatabase = ... try await db.query( "INSERT INTO events (name) VALUES (?)", [MySQLData(string: "user_login")], onMetadata: { metadata in print("Last insert ID: \(metadata.lastInsertID ?? 0)") } ).get() ``` -------------------------------- ### connect(to:username:database:password:tlsConfiguration:serverHostname:logger:on:) Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLConnection.md Establishes a connection to a MySQL server. It manages the underlying network channel and handles authentication. ```APIDOC ## connect(to:username:database:password:tlsConfiguration:serverHostname:logger:on:) ### Description Establishes a connection to a MySQL server. It manages the underlying network channel and handles authentication. ### Method Signature ```swift public static func connect( to socketAddress: SocketAddress, username: String, database: String, password: String? = nil, tlsConfiguration: TLSConfiguration? = .makeClientConfiguration(), serverHostname: String? = nil, logger: Logger = .init(label: "codes.vapor.mysql"), on eventLoop: any EventLoop ) -> EventLoopFuture ``` ### Parameters #### Path Parameters There are no path parameters for this method. #### Query Parameters There are no query parameters for this method. #### Request Body There is no request body for this method. ### Parameters Table | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | socketAddress | `SocketAddress` | — | The server address. Can be created with `SocketAddress(ipAddress:port:)`, `SocketAddress(unixDomainSocketPath:)`, or `SocketAddress.makeAddressResolvingHost(_:port:)` | | username | `String` | — | Username for authentication | | database | `String` | — | Default database/schema name | | password | `String?` | `nil` | Password for authentication | | tlsConfiguration | `TLSConfiguration?` | `.makeClientConfiguration()` | TLS configuration. Pass `nil` to disable TLS | | serverHostname | `String?` | `nil` | Server hostname for TLS certificate validation | | logger | `Logger` | `.init(label: "codes.vapor.mysql")` | Logger instance for debugging | | eventLoop | `any EventLoop` | — | The NIO event loop to use for async operations | ### Returns An `EventLoopFuture` that completes when the connection is established and authenticated, or fails with a `MySQLError`. ### Example ```swift import MySQLNIO import NIO let eventLoop: EventLoop = ... let conn = try await MySQLConnection.connect( to: .makeAddressResolvingHost("localhost", port: 3306), username: "root", database: "myapp", password: "password", on: eventLoop ).get() defer { try? conn.close().wait() } ``` ``` -------------------------------- ### Accessing Column Data by Name Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLRow.md Retrieves a column's MySQLData by its name, with an optional table filter for disambiguation. Examples show accessing string, integer, and date types. ```swift let row: any MySQLRow = ... if let name = row.column("name")?.string { print("Name: \(name)") } if let age = row.column("age")?.int { print("Age: \(age)") } if let created = row.column("created_at")?.date { print("Created: \(created)") } ``` -------------------------------- ### MySQLConnection Connect Method Signature Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/configuration.md The signature for the `connect` method shows all available configuration parameters. ```swift public static func connect( to socketAddress: SocketAddress, username: String, database: String, password: String? = nil, tlsConfiguration: TLSConfiguration? = .makeClientConfiguration(), serverHostname: String? = nil, logger: Logger = .init(label: "codes.vapor.mysql"), on eventLoop: any EventLoop ) -> EventLoopFuture ``` -------------------------------- ### Getting Metadata from Query Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-QueryMetadata.md Metadata is provided via the `onMetadata` callback parameter in query methods. This allows you to access information like affected rows and the last insert ID after a query has been executed. ```APIDOC ## Getting Metadata from Query Metadata is provided via the `onMetadata` callback parameter in query methods: ### With Row Callback ```swift let db: any MySQLDatabase = ... var rowCount = 0 try await db.query( "SELECT * FROM users", onRow: { row in rowCount += 1 print(row) }, onMetadata: { metadata in print("Query affected \(metadata.affectedRows) rows") print("Inserted ID: \(metadata.lastInsertID ?? 0)") } ).get() ``` ### Without Row Callback ```swift let db: any MySQLDatabase = ... try await db.query( "INSERT INTO events (name) VALUES (?)", [MySQLData(string: "user_login")], onMetadata: { metadata in print("Last insert ID: \(metadata.lastInsertID ?? 0)") } ).get() ``` ``` -------------------------------- ### Configuring MySQL Connection with Custom Logger Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/INDEX.md Shows how to create a MySQL connection that uses a specific logger instance for all its operations, allowing for customized logging. ```swift let db = conn.logging(to: myLogger) // All queries on db will use myLogger ``` -------------------------------- ### MySQLData Literal Initializers Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Demonstrates the use of literal initializers for String, Int, and Bool types, allowing for concise creation of MySQLData instances. ```swift let strData: MySQLData = "hello" let intData: MySQLData = 42 let boolData: MySQLData = true ``` -------------------------------- ### MySQLData Initialization Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Provides various initializers for creating MySQLData instances from different Swift types, including raw data, strings, integers, booleans, and more complex types like JSON. ```APIDOC ## Initialization ### `init(type:format:buffer:isUnsigned:)` Creates a `MySQLData` with raw type information and buffer. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | type | `MySQLProtocol.DataType` | — | MySQL data type | | format | `Format` | `.binary` | Data format: `.binary` or `.text` | | buffer | `ByteBuffer?` | — | Raw bytes or nil for NULL | | isUnsigned | `Bool` | `false` | Whether the value is unsigned | ### Convenience Initializers #### `init(string:)` Creates `MySQLData` from a String. **Example:** `MySQLData(string: "hello")` #### `init(int:)` Creates `MySQLData` from an Int (64-bit). **Example:** `MySQLData(int: 42)` #### `init(bool:)` Creates `MySQLData` from a Bool. **Example:** `MySQLData(bool: true)` #### `init(double:)` Creates `MySQLData` from a Double. **Example:** `MySQLData(double: 3.14159)` #### `init(decimal:)` Creates `MySQLData` from a Decimal. **Example:** `MySQLData(decimal: Decimal(string: "123.45")!)` #### `init(float:)` Creates `MySQLData` from a Float. **Example:** `MySQLData(float: 1.5)` #### `init(uuid:)` Creates `MySQLData` from a UUID. **Example:** `MySQLData(uuid: UUID())` #### `init(date:)` Creates `MySQLData` from a Date. **Example:** `MySQLData(date: Date())` #### `init(time:)` Creates `MySQLData` from a MySQLTime. **Example:** `MySQLData(time: MySQLTime(year: 2024, month: 5, day: 24))` #### `init(json:)` Creates `MySQLData` from a JSON-encodable value. | Parameter | Type | Description | |-----------|------|-------------| | value | `any Encodable` | Value conforming to Encodable | **Example:** ```swift struct Person: Encodable { let name: String } let data = try MySQLData(json: Person(name: "Alice")) ``` ### Literal Initializers `MySQLData` conforms to `ExpressibleByStringLiteral`, `ExpressibleByIntegerLiteral`, and `ExpressibleByBooleanLiteral`: ```swift let strData: MySQLData = "hello" let intData: MySQLData = 42 let boolData: MySQLData = true ``` ``` -------------------------------- ### Enable Dynamic Logging for Queries Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/configuration.md Wraps an existing connection to enable logging for all subsequent queries using a specified logger. This is useful for debugging specific query executions. ```swift let db = conn as (any MySQLDatabase) let loggingDb = db.logging(to: debugLogger) // Now queries on loggingDb use debugLogger ``` -------------------------------- ### Connect via IP Address Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/configuration.md Establishes a connection using a direct IP address and port. ```swift let socketAddr = SocketAddress(ipAddress: "192.168.1.100", port: 3306) let conn = try await MySQLConnection.connect( to: socketAddr, username: "app_user", database: "myapp", password: "secure_password", on: eventLoop ).get() ``` -------------------------------- ### Checking for SSL Support in MySQL Capabilities Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/types.md Demonstrates how to check if the MySQL server supports SSL connections using capability flags. This is useful for securing communication. ```swift let flags: MySQLProtocol.CapabilityFlags = [.CLIENT_SSL, .CLIENT_SECURE_CONNECTION] if flags.contains(.CLIENT_SSL) { // Server supports SSL } ``` -------------------------------- ### Create MySQLData for Query Parameters Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/INDEX.md Illustrates the creation of MySQLData objects for various Swift types to be used as parameters in SQL queries. ```swift MySQLData(string: "value") MySQLData(int: 42) MySQLData(bool: true) MySQLData(date: Date()) MySQLData(uuid: UUID()) MySQLData(double: 3.14) MySQLData(decimal: Decimal(string: "123.45")!) MySQLData(time: MySQLTime(date: Date())) try MySQLData(json: encodableValue) ``` -------------------------------- ### MySQLConnection - Connect Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/README.md Establishes a new connection to a MySQL database. This is the primary method for initiating a connection. ```APIDOC ## MySQLConnection.connect ### Description Creates and establishes a connection to a MySQL database server. ### Method `connect(to:username:database:password:on:)` ### Parameters - **host** (String) - The hostname or IP address of the MySQL server. - **port** (Int) - The port number for the MySQL server (default is 3306). - **username** (String) - The username for authentication. - **database** (String) - The name of the database to connect to. - **password** (String) - The password for authentication. - **on** (EventLoop) - The event loop to use for the connection. ### Request Example ```swift try await MySQLConnection.connect( to: .makeAddressResolvingHost("localhost", port: 3306), username: "user", database: "db", password: "pass", on: eventLoop ).get() ``` ``` -------------------------------- ### MySQLConnection.connect Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/INDEX.md Establishes a new connection to a MySQL server. This is the primary method for initiating a connection to the database. ```APIDOC ## MySQLConnection.connect ### Description Establishes a new connection to a MySQL server using provided host, port, username, database, and password. ### Method `connect` ### Endpoint N/A (SDK method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift let conn = try await MySQLConnection.connect( to: .makeAddressResolvingHost("localhost", port: 3306), username: "root", database: "myapp", password: "password", on: eventLoop ).get() ``` ### Response #### Success Response A `MySQLConnection` object representing the active connection. #### Response Example (Connection object, not directly representable as JSON) ERROR HANDLING: - Throws `MySQLError` on connection failure. ``` -------------------------------- ### Bind String to MySQL Query Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLDataConvertible.md Shows how to use a `String` directly as a query parameter, leveraging its `MySQLDataConvertible` conformance. ```swift let name = "Alice" try await db.query("SELECT * FROM users WHERE name = ?", [name.mysqlData!]).get() ``` -------------------------------- ### Initialize from MySQLData Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLDataConvertible.md Initializes a Swift type from `MySQLData`. Returns `nil` if the conversion is not possible. ```swift init?(mysqlData: MySQLData) ``` -------------------------------- ### send(_:logger:) Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLConnection.md Sends a MySQL command to the server for execution. ```APIDOC ## send(_:logger:) ### Description Sends a MySQL command to the server for execution. ### Method Signature ```swift public func send(_ command: any MySQLCommand, logger: Logger) -> EventLoopFuture ``` ### Parameters #### Path Parameters There are no path parameters for this method. #### Query Parameters There are no query parameters for this method. #### Request Body There is no request body for this method. ### Parameters Table | Parameter | Type | Description | |-----------|------|-------------| | command | `any MySQLCommand` | The command to execute | | logger | `Logger` | Logger for the command | ### Returns An `EventLoopFuture` that completes when the command has been processed. Throws `MySQLError.closed` if the connection has been closed. ### Example ```swift let conn: MySQLConnection = ... let command: MySQLCommand = ... // Define your MySQL command let logger: Logger = ... // Define your logger try await conn.send(command, logger: logger).get() ``` ``` -------------------------------- ### MySQLData Initialization from JSON Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Creates MySQLData from any Encodable value by encoding it to JSON. Requires the value to conform to the Encodable protocol. ```swift public init(json value: any Encodable) throws ``` -------------------------------- ### MySQLRow Initializer Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLRow.md Initializes a new MySQLRow with specified data format, column definitions, and raw values. ```swift public init( format: MySQLData.Format, columnDefinitions: [MySQLProtocol.ColumnDefinition41], values: [ByteBuffer?] ) ``` -------------------------------- ### MySQLData Convenience Initializers Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Provides convenience initializers for creating MySQLData from common Swift types like String, Int, Bool, Double, Decimal, Float, UUID, Date, and MySQLTime. ```swift public init(string: String) ``` ```swift public init(int: Int) ``` ```swift public init(bool: Bool) ``` ```swift public init(double: Double) ``` ```swift public init(decimal: Decimal) ``` ```swift public init(float: Float) ``` ```swift public init(uuid: UUID) ``` ```swift public init(date: Date) ``` ```swift public init(time: MySQLTime) ``` -------------------------------- ### Enable Trace Logging for MySQLNIO Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/protocol-internals.md Configure a logger to capture detailed trace information about MySQL protocol interactions, including packet details and state transitions. ```swift var logger = Logger(label: "mysqlnio") logger.logLevel = .trace let conn = try await MySQLConnection.connect( ..., logger: logger, ... ).get() ``` -------------------------------- ### Wrap MySQLDatabase with a Logger Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLDatabase.md Use this method to create a new `MySQLDatabase` instance that logs its operations to a specified `Logger`. This is useful for debugging and monitoring database interactions. ```swift var logger = Logger(label: "database") let loggingDb = db.logging(to: logger) ``` -------------------------------- ### MySQLData Initializer with Raw Information Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLData.md Initializes MySQLData with raw type information and an optional buffer. Allows specifying data format and unsigned status. ```swift public init( type: MySQLProtocol.DataType, format: Format = .binary, buffer: ByteBuffer?, isUnsigned: Bool = false ) ``` -------------------------------- ### Execute Simple Query and Return All Rows Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLDatabase.md Executes a simple SQL query without parameters and returns all rows as an array. Data is returned in text format. ```swift let db: any MySQLDatabase = ... let rows = try await db.simpleQuery("SELECT @@version").get() print(rows) // [["@@version": "8.0.x"]] ``` -------------------------------- ### COM_STMT_PREPARE Command Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/protocol-internals.md Prepares an SQL statement on the server, returning a statement ID for later execution. This is useful for optimizing repeated queries. ```swift MySQLProtocol.COM_STMT_PREPARE(query: String) ``` -------------------------------- ### Default Metadata Handling Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-QueryMetadata.md Explains how metadata is handled when an `onMetadata` callback is not explicitly provided, and how to ensure metadata is accessible by always providing the callback. ```APIDOC ## Default Metadata If you don't provide an `onMetadata` callback, an empty handler is used: ```swift let rows = try await db.query("SELECT * FROM users").get() // Metadata is computed but not accessible ``` To access metadata, always provide the callback: ```swift var metadata: MySQLQueryMetadata? let rows = try await db.query( "SELECT * FROM users", onMetadata: { md in metadata = md } ).get() print("Affected rows: \(metadata?.affectedRows ?? 0)") ``` ``` -------------------------------- ### Connect with Default TLS Configuration Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/configuration.md Uses the default client TLS configuration for encrypted connections. TLS is enabled by default. ```swift let conn = try await MySQLConnection.connect( to: socketAddress, username: "user", database: "db", // tlsConfiguration uses default client config on: eventLoop ).get() ``` -------------------------------- ### MySQLDatabase - Simple Query with Callback Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/README.md Executes a plain SQL query and processes rows using a callback. ```APIDOC ## MySQLDatabase.simpleQuery (with Callback) ### Description Executes a plain SQL query and processes each returned row using a provided callback closure. ### Method `simpleQuery(_:onRow:)` ### Parameters - **sql** (String) - The SQL query string. - **onRow** ((MySQLRow) -> Void) - A closure that is executed for each row returned by the query. ### Request Example ```swift try await db.simpleQuery("SELECT name FROM customers", onRow: { row in if let name = row.column("name")?.string { print("Customer: \(name)") } }).get() ``` ``` -------------------------------- ### Accessing MySQL Row Columns Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/INDEX.md Demonstrates how to retrieve column data from a MySQLRow by name or by name and table. Also shows how to inspect the row's structure. ```swift let row: MySQLRow = ... // Get column by name row.column("column_name") // MySQLData? // Get column by name and table row.column("name", table: "users") // MySQLData? // Inspect structure row.columnDefinitions // [MySQLProtocol.ColumnDefinition41] row.format // .binary or .text row.values // [ByteBuffer?] ``` -------------------------------- ### Initialize MySQLTime from MySQLData Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLTime.md Constructs a MySQLTime instance from MySQLData, implementing the MySQLDataConvertible protocol. Returns nil if the data is not valid time information. ```swift public init?(mysqlData: MySQLData) ``` -------------------------------- ### MySQLRow Initialization Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLRow.md Initializes a new MySQLRow with specified format, column definitions, and raw values. This is used internally by MySQLNIO to construct rows from query results. ```APIDOC ## init(format:columnDefinitions:values:) ### Description Creates a new `MySQLRow` instance. ### Parameters #### Path Parameters - **format** (`MySQLData.Format`) - Required - Format of the data: `.binary` or `.text` - **columnDefinitions** (`[MySQLProtocol.ColumnDefinition41]`) - Required - Metadata for each column - **values** (`[ByteBuffer?]`) - Required - Raw byte buffers for each column value ``` -------------------------------- ### MySQLDatabase - Logging Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/README.md Creates a logging wrapper for database operations. ```APIDOC ## MySQLDatabase.logging ### Description Creates a wrapper around the current database connection that logs all executed queries. ### Method `logging(to:)` ### Parameters - **logger** (Logger) - The logger instance to use for logging queries. ### Request Example ```swift let logger = Logger(label: "com.example.mysql") let loggingDb = db.logging(to: logger) // Now, any queries executed via 'loggingDb' will be logged. let rows = try await loggingDb.query("SELECT * FROM logs").get() ``` ``` -------------------------------- ### `logging(to:)` Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/api-reference-MySQLDatabase.md Returns a new `MySQLDatabase` wrapper that logs to the provided logger. This is useful for debugging and monitoring database interactions. ```APIDOC ## `logging(to:)` ### Description Returns a new `MySQLDatabase` wrapper that logs to the provided logger. ### Method Swift Function ### Signature `public func logging(to logger: Logger) -> any MySQLDatabase` ### Parameters #### Parameters - **logger** (`Logger`) - Required - Logger instance for logging ### Returns A new `MySQLDatabase` implementation that uses the provided logger. ### Example ```swift var logger = Logger(label: "database") let loggingDb = db.logging(to: logger) ``` ``` -------------------------------- ### COM_STMT_EXECUTE Command Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/protocol-internals.md Executes a previously prepared statement with provided parameter values in binary format. This is efficient for queries with varying parameters. ```swift MySQLProtocol.COM_STMT_EXECUTE( statementID: UInt32, flags: [ExecuteFlag], values: [MySQLData] ) ``` -------------------------------- ### Connect with Custom TLS Configuration Source: https://github.com/vapor/mysql-nio/blob/main/_autodocs/configuration.md Allows for detailed customization of TLS settings, such as disabling certificate verification. Ensure `serverHostname` is set if needed for validation. ```swift import NIOSSL var tlsConfig = TLSConfiguration.makeClientConfiguration() tlsConfig.certificateVerification = .none // Don't verify server cert // ... other customizations let conn = try await MySQLConnection.connect( to: socketAddress, username: "user", database: "db", tlsConfiguration: tlsConfig, serverHostname: "db.example.com", on: eventLoop ).get() ```