该项目提供使用 XML Web 发布接口访问 FileMaker Server 数据库的功能。
此软件包使用 Swift Package Manager 构建,并且是 Perfect 项目的一部分。 它被设计为独立运行,因此不需要作为 Perfect 服务器应用程序的一部分运行。
请确保您已安装并激活最新的 Swift 4.1.1 工具链。
请确保您已安装 curl 和 libxml2。
sudo apt-get install libcurl4-openssl-dev libxml2-dev
将此项目作为依赖项添加到您的 Package.swift 文件中。
.package(url: "https://github.com/PerfectlySoft/Perfect-FileMaker.git", from: "3.0.0")
要使用此软件包,请 import PerfectFileMaker
。
此代码片段连接到服务器并让其列出所有托管的数据库。
let fms = FileMakerServer(host: testHost, port: testPort, userName: testUserName, password: testPassword)
fms.databaseNames {
result in
do {
// Get the list of names
let names = try result()
for name in names {
print("Got a database name \(name)")
}
} catch FMPError.serverError(let code, let msg) {
print("Got a server error \(code) \(msg)")
} catch let e {
print("Got an unexpected error \(e)")
}
}
列出特定数据库中的所有布局。
let fms = FileMakerServer(host: testHost, port: testPort, userName: testUserName, password: testPassword)
fms.layoutNames(database: "FMServer_Sample") {
result in
guard let names = try? result() else {
return // got an error
}
for name in names {
print("Got a layout name \(name)")
}
}
列出特定布局上的所有字段名称。
let fms = FileMakerServer(host: testHost, port: testPort, userName: testUserName, password: testPassword)
fms.layoutInfo(database: "FMServer_Sample", layout: "Task Details") {
result in
guard let layoutInfo = try? result() else {
return // error
}
let fieldsByName = layoutInfo.fieldsByName
for (name, value) in fieldsByName {
print("Field \(name) = \(value)")
}
}
执行 findall 并打印所有字段名称和值。
let query = FMPQuery(database: "FMServer_Sample", layout: "Task Details", action: .findAll)
let fms = FileMakerServer(host: testHost, port: testPort, userName: testUserName, password: testPassword)
fms.query(query) {
result in
guard let resultSet = try? result() else {
return // error
}
let fields = resultSet.layoutInfo.fields
let records = resultSet.records
let recordCount = records.count
for i in 0..<recordCount {
let rec = records[i]
for field in fields {
switch field {
case .fieldDefinition(let def):
let fieldName = def.name
if let fnd = rec.elements[fieldName], case .field(_, let fieldValue) = fnd {
print("Normal field: \(fieldName) = \(fieldValue)")
}
case .relatedSetDefinition(let name, _):
guard let fnd = rec.elements[name], case .relatedSet(_, let relatedRecs) = fnd else {
continue
}
print("Relation: \(name)")
for relatedRec in relatedRecs {
for relatedRow in relatedRec.elements.values {
if case .field(let fieldName, let fieldValue) = relatedRow {
print("\tRelated field: \(fieldName) = \(fieldValue)")
}
}
}
}
}
}
}
要添加 skip 和 max,上述查询将进行如下修改
// Skip two records and return a max of two records.
let query = FMPQuery(database: "FMServer_Sample", layout: "Task Details", action: .findAll)
.skipRecords(2).maxRecords(2)
...
查找字段 "Status" 的值为 "In Progress" 的所有记录。
let qfields = [FMPQueryFieldGroup(fields: [FMPQueryField(name: "Status", value: "In Progress")])]
let query = FMPQuery(database: "FMServer_Sample", layout: "Task Details", action: .find)
.queryFields(qfields)
let fms = FileMakerServer(host: testHost, port: testPort, userName: testUserName, password: testPassword)
fms.query(query) {
result in
guard let resultSet = try? result() else {
return // error
}
let fields = resultSet.layoutInfo.fields
let records = resultSet.records
let recordCount = records.count
for i in 0..<recordCount {
let rec = records[i]
for field in fields {
switch field {
case .fieldDefinition(let def):
let fieldName = def.name
if let fnd = rec.elements[fieldName], case .field(_, let fieldValue) = fnd {
print("Normal field: \(fieldName) = \(fieldValue)")
if name == "Status", case .text(let tstStr) = fieldValue {
print("Status == \(tstStr)")
}
}
case .relatedSetDefinition(let name, _):
guard let fnd = rec.elements[name], case .relatedSet(_, let relatedRecs) = fnd else {
continue
}
print("Relation: \(name)")
for relatedRec in relatedRecs {
for relatedRow in relatedRec.elements.values {
if case .field(let fieldName, let fieldValue) = relatedRow {
print("\tRelated field: \(fieldName) = \(fieldValue)")
}
}
}
}
}
}
}