服务器端 Swift 和 Vapor Ubuntu
Serverside Swift and Vapor on Ubuntu
我正在尝试从服务器端 Swift 编写一个基于 Project2 的 API by Paul Hudson
https://www.hackingwithswift.com/store/server-side-swift
我是运行宁:
Swift 版本 5.0 (swift-5.0-RELEASE)
目标:x86_64-unknown-linux-gnu
和
Vapor 工具箱:3.1.10
在 Ubuntu 18.04.3 LTS(GNU/Linux 4.15.0-66-通用 x86_64)
想法是使用 Fluent 和 SQLite 来维护 (CRUD) 属性 条记录。
configure.swift的相关部分是:
let directoryConfig = DirectoryConfig.detect()
services.register(directoryConfig)
try services.register(FluentSQLiteProvider())
var databaseConfig = DatabasesConfig()
let db = try SQLiteDatabase(storage: .file(path: "\(directoryConfig.workDir)properties.db"))
databaseConfig.add(database: db, as: .sqlite)
services.register(databaseConfig)
var migrationConfig = MigrationConfig()
migrationConfig.add(model: Property.self, database: .sqlite)
services.register(migrationConfig)
在 Routes.swift 我有这个:
router.post(Property.self, at: "properties", "create") { req, property -> Future<Property> in
return property.save(on: req)
}
router.get("properties", "list") { req -> Future<[Property]> in
return Property.query(on: req).all()
}
而Property.swift是这样的:
// Property.swift
//
// Created by Peter Matthews on 07/12/2019.
//
import Fluent
import FluentSQLite
import Foundation
import Vapor
enum TenureType: String, Codable {
case freehold
case cross_lease
case unit_title
// etc...
}
enum PropertyType: String, Codable {
case commercial
case office
case industrial
case retail
// etc...
}
struct Property: Content, SQLiteUUIDModel, Migration {
var id: UUID?
var tenureType: TenureType? // var tenureType: String?
var propertyType: PropertyType? // var propertyType: String?
// etc...
}
当 tenureType
和 propertyType
被定义为 String?
时一切正常,但我认为有充分的理由使用枚举来指定 [=17= 的可能值] 和 propertyType
.
Terminal output:
pm@PHQ:~/PropertyHQ$ vapor run
Running PropertyHQ ...
[ INFO ] Migrating 'sqlite' database (/home/pm/PropertyHQ/.build/checkouts/fluent/Sources/Fluent/Migration/MigrationConfig.swift:69)
[ INFO ] Migrations complete (/home/pm/PropertyHQ/.build/checkouts/fluent/Sources/Fluent/Migration/MigrationConfig.swift:73)
Running default command: .build/debug/Run serve
问题是,当我尝试为 tenureType
和 propertyType
使用枚举时,应用程序构建得很好,但是当我 运行 vapor 服务器时,我收到此错误。
Terminal output:
pm@PHQ:~/PropertyHQ$ vapor run
Running PropertyHQ ...
[ INFO ] Migrating 'sqlite' database (/home/pm/PropertyHQ/.build/checkouts/fluent/Sources/Fluent/Migration/MigrationConfig.swift:69)
[ INFO ] Preparing migration 'Property' (/home/pm/PropertyHQ/.build/checkouts/fluent/Sources/Fluent/Migration/Migrations.swift:111)
⚠️ [DecodingError.dataCorrupted: Cannot initialize TenureType from invalid String value 1]
Error: Run failed.
pm@PHQ:~/PropertyHQ$
当我将 tenureType
和 propertyType
指定为可选(我认为它们应该是)时,错误值为 1 - 当它们不是可选时,错误值为 0。
我应该补充一点,这个错误只会在我第一次 运行 服务器时发生,即:当它创建(空)数据库时。如果我第一次 运行 将 tenureType
和 propertyType
定义为 String?
它 运行 没问题然后我可以将它们更改为枚举并继续工作正常。
您需要使 enum
符合 SQLiteEnumType
和 ReflectionDecodable
。您还需要为每种情况提供字符串值。以您的 TenureType
为例,尝试:
enum TenureType: String, Codable, SQLiteEnumType, ReflectionDecodable {
static func reflectDecoded() throws -> (TenureType, TenureType) {
return ( .freehold, .cross_lease )
}
case freehold = "freehold"
case cross_lease = "cross_lease"
case unit_title = "unit_title"
// etc...
}
我正在尝试从服务器端 Swift 编写一个基于 Project2 的 API by Paul Hudson https://www.hackingwithswift.com/store/server-side-swift
我是运行宁:
Swift 版本 5.0 (swift-5.0-RELEASE) 目标:x86_64-unknown-linux-gnu
和
Vapor 工具箱:3.1.10
在 Ubuntu 18.04.3 LTS(GNU/Linux 4.15.0-66-通用 x86_64)
想法是使用 Fluent 和 SQLite 来维护 (CRUD) 属性 条记录。
configure.swift的相关部分是:
let directoryConfig = DirectoryConfig.detect()
services.register(directoryConfig)
try services.register(FluentSQLiteProvider())
var databaseConfig = DatabasesConfig()
let db = try SQLiteDatabase(storage: .file(path: "\(directoryConfig.workDir)properties.db"))
databaseConfig.add(database: db, as: .sqlite)
services.register(databaseConfig)
var migrationConfig = MigrationConfig()
migrationConfig.add(model: Property.self, database: .sqlite)
services.register(migrationConfig)
在 Routes.swift 我有这个:
router.post(Property.self, at: "properties", "create") { req, property -> Future<Property> in
return property.save(on: req)
}
router.get("properties", "list") { req -> Future<[Property]> in
return Property.query(on: req).all()
}
而Property.swift是这样的:
// Property.swift
//
// Created by Peter Matthews on 07/12/2019.
//
import Fluent
import FluentSQLite
import Foundation
import Vapor
enum TenureType: String, Codable {
case freehold
case cross_lease
case unit_title
// etc...
}
enum PropertyType: String, Codable {
case commercial
case office
case industrial
case retail
// etc...
}
struct Property: Content, SQLiteUUIDModel, Migration {
var id: UUID?
var tenureType: TenureType? // var tenureType: String?
var propertyType: PropertyType? // var propertyType: String?
// etc...
}
当 tenureType
和 propertyType
被定义为 String?
时一切正常,但我认为有充分的理由使用枚举来指定 [=17= 的可能值] 和 propertyType
.
Terminal output:
pm@PHQ:~/PropertyHQ$ vapor run
Running PropertyHQ ...
[ INFO ] Migrating 'sqlite' database (/home/pm/PropertyHQ/.build/checkouts/fluent/Sources/Fluent/Migration/MigrationConfig.swift:69)
[ INFO ] Migrations complete (/home/pm/PropertyHQ/.build/checkouts/fluent/Sources/Fluent/Migration/MigrationConfig.swift:73)
Running default command: .build/debug/Run serve
问题是,当我尝试为 tenureType
和 propertyType
使用枚举时,应用程序构建得很好,但是当我 运行 vapor 服务器时,我收到此错误。
Terminal output:
pm@PHQ:~/PropertyHQ$ vapor run
Running PropertyHQ ...
[ INFO ] Migrating 'sqlite' database (/home/pm/PropertyHQ/.build/checkouts/fluent/Sources/Fluent/Migration/MigrationConfig.swift:69)
[ INFO ] Preparing migration 'Property' (/home/pm/PropertyHQ/.build/checkouts/fluent/Sources/Fluent/Migration/Migrations.swift:111)
⚠️ [DecodingError.dataCorrupted: Cannot initialize TenureType from invalid String value 1]
Error: Run failed.
pm@PHQ:~/PropertyHQ$
当我将 tenureType
和 propertyType
指定为可选(我认为它们应该是)时,错误值为 1 - 当它们不是可选时,错误值为 0。
我应该补充一点,这个错误只会在我第一次 运行 服务器时发生,即:当它创建(空)数据库时。如果我第一次 运行 将 tenureType
和 propertyType
定义为 String?
它 运行 没问题然后我可以将它们更改为枚举并继续工作正常。
您需要使 enum
符合 SQLiteEnumType
和 ReflectionDecodable
。您还需要为每种情况提供字符串值。以您的 TenureType
为例,尝试:
enum TenureType: String, Codable, SQLiteEnumType, ReflectionDecodable {
static func reflectDecoded() throws -> (TenureType, TenureType) {
return ( .freehold, .cross_lease )
}
case freehold = "freehold"
case cross_lease = "cross_lease"
case unit_title = "unit_title"
// etc...
}