1
votes

I'm new at Vapor and I wanted to try to connect my MySQL database. I found on official documentation how to do it but when I try to send a query it throws an error:

No services are available for 'DatabaseConnectionPoolCache'. (Container.swift:112)

I just copy-paste the code from documentation and it doesn`t work. Could someone help me to found out why?

I have [email protected] on Mojave. Actually simple requests work well, for example :

router.get("hey") { req in
    return "Stas, hey"
}

Code in configure.swift :

import FluentSQLite
import MySQL
import Vapor

/// Called before your application initializes.
public func configure(_ config: inout Config, _ env: inout Environment, _ services: inout Services) throws {
    /// Register providers first
    try services.register(FluentSQLiteProvider())
    try services.register(MySQLProvider())

    /// Register routes to the router
    let router = EngineRouter.default()
    try routes(router)
    services.register(router, as: Router.self)

    /// Register middleware
    var middlewares = MiddlewareConfig() // Create _empty_ middleware config
    /// middlewares.use(FileMiddleware.self) // Serves files from `Public/` directory
    middlewares.use(ErrorMiddleware.self) // Catches errors and converts to HTTP response
    services.register(middlewares)

    // Configure a SQLite database
    let sqlite = try SQLiteDatabase(storage: .memory)

    /// Register the configured SQLite database to the database config.
    var databases = DatabasesConfig()
    databases.add(database: sqlite, as: .sqlite)
    services.register(databases)

    /// Configure migrations
    var migrations = MigrationConfig()
    migrations.add(model: Todo.self, database: .sqlite)
    services.register(migrations)

    //Configure a MySQL database
    let mysql = try MySQLDatabase(config: MySQLDatabaseConfig(
        hostname: "127.0.0.1",
        port: 3306,
        username: "root",
        password: "7374",
        database: "WORK_TIME"))

    ///Register to the congig
    var mysqlDatabases = DatabasesConfig()
    mysqlDatabases.add(database: mysql, as: .mysql)
    services.register(mysqlDatabases) 
}

My query in main.swift :

public struct MySQLVersion: Codable {
    let version: String
}

router.get("sql") { req in
    return req.withPooledConnection(to: .mysql) {conn in
        return conn.raw("SELECT @@version as version")
            .all(decoding: MySQLVersion.self)
        }.map { rows in
            return rows[0].version
    }
}

It should return the version of my MySQL but it throws a strange error.

2

2 Answers

2
votes

Your issue is that there is some leftover SQLite stuff from the original project template.

Start by removing the fluent-sqlite dependency from your Package.swift file and the FluentSQLite target from any target dependencies. Then run swift package update (and vapor xcode if you use Xcode) in your terminal.

Now that you have removed the FluentSQLite dependency from your project, you should be able to follow to compiler errors to fix your issue. Here are the ones I found:


import FluentSQLite
import MySQL

Should be:

import FluentMySQL

try services.register(FluentSQLiteProvider())
try services.register(MySQLProvider())

Should be

try services.register(FluentMySQLProvider())

Delete this, since you are using MySQL instead of SQLite:

// Configure a SQLite database
let sqlite = try SQLiteDatabase(storage: .memory)

/// Register the configured SQLite database to the database config.
var databases = DatabasesConfig()
databases.add(database: sqlite, as: .sqlite)
services.register(databases)

migrations.add(model: Todo.self, database: .sqlite)

Should be

migrations.add(model: Todo.self, database: .mysql)

I think that covers everything. Your /sql route should work now.

1
votes

To solve this problem you should get rid of all leftover SQLite stuff from the original project and have to write your routes in routes.swift