| @@ -11,7 +11,7 @@ struct FuelEntryV2Controller: RouteCollection { | |||||
| func boot(routes: RoutesBuilder) throws { | func boot(routes: RoutesBuilder) throws { | ||||
| let fuelEntries = routes.grouped("fuel_entries") | let fuelEntries = routes.grouped("fuel_entries") | ||||
| fuelEntries.get(use: index) | fuelEntries.get(use: index) | ||||
| fuelEntries.get("with-images", use: getAllEntriesWithImages) | |||||
| // fuelEntries.get("with-images", use: getAllEntriesWithImages) | |||||
| fuelEntries.post(use: create) | fuelEntries.post(use: create) | ||||
| // fuelEntries.post("upload-image", use: uploadImage) | // fuelEntries.post("upload-image", use: uploadImage) | ||||
| fuelEntries.group(":fuelEntryID") { fuelEntry in | fuelEntries.group(":fuelEntryID") { fuelEntry in | ||||
| @@ -23,51 +23,58 @@ struct FuelEntryV2Controller: RouteCollection { | |||||
| try await FuelEntry.query(on: req.db).all() | try await FuelEntry.query(on: req.db).all() | ||||
| } | } | ||||
| func getAllEntriesWithImages(req: Request) async throws -> [FuelEntry] { | |||||
| let fuelEntries = try await FuelEntry.query(on: req.db).all() | |||||
| for var fuelEntry in fuelEntries { | |||||
| if let imagePath = fuelEntry.image { | |||||
| let fileURL = URL(fileURLWithPath: imagePath) | |||||
| if let imageData = try? Data(contentsOf: fileURL) { | |||||
| fuelEntry.imageData = imageData | |||||
| } | |||||
| } | |||||
| } | |||||
| return fuelEntries | |||||
| } | |||||
| // func getAllEntriesWithImages(req: Request) async throws -> [FuelEntry] { | |||||
| // let fuelEntries = try await FuelEntry.query(on: req.db).all() | |||||
| // | |||||
| // for var fuelEntry in fuelEntries { | |||||
| // if let imagePath = fuelEntry.image { | |||||
| // let fileURL = URL(fileURLWithPath: imagePath) | |||||
| // if let imageData = try? Data(contentsOf: fileURL) { | |||||
| // fuelEntry.imageData = imageData | |||||
| // } | |||||
| // } | |||||
| // } | |||||
| // return fuelEntries | |||||
| // } | |||||
| func create(req: Request) async throws -> [FuelEntry] { | func create(req: Request) async throws -> [FuelEntry] { | ||||
| let fuelEntries = try await req.content.decode([FuelEntry].self) | |||||
| let directory = DirectoryConfiguration.detect().workingDirectory + "Images/" | |||||
| var updatedFuelEntries: [FuelEntry] = [] | |||||
| for fuelEntry in fuelEntries { | |||||
| let updatedFuelEntry = try await { () async throws -> FuelEntry in | |||||
| var updatedFuelEntry = fuelEntry | |||||
| if let imageData = updatedFuelEntry.imageData { | |||||
| let imageFilename = "\(updatedFuelEntry.id!).png" | |||||
| let tempImageURL = URL(fileURLWithPath: directory + imageFilename) | |||||
| try await imageData.write(to: tempImageURL) | |||||
| updatedFuelEntry.image = tempImageURL.absoluteString | |||||
| } | |||||
| do { | |||||
| _ = try await updatedFuelEntry.save(on: req.db) | |||||
| return updatedFuelEntry | |||||
| } catch { | |||||
| throw Abort(.internalServerError, reason: "Error saving FuelEntry: \(error)") | |||||
| } | |||||
| }() | |||||
| updatedFuelEntries.append(updatedFuelEntry) | |||||
| } | |||||
| return updatedFuelEntries | |||||
| let fuelEntry = try req.content.decode([FuelEntry].self) | |||||
| try await fuelEntry.create(on: req.db) | |||||
| return fuelEntry | |||||
| } | } | ||||
| //Create with image file written to server storage instead of database | |||||
| // func create(req: Request) async throws -> [FuelEntry] { | |||||
| // let fuelEntries = try await req.content.decode([FuelEntry].self) | |||||
| // let directory = DirectoryConfiguration.detect().workingDirectory + "Images/" | |||||
| // | |||||
| // var updatedFuelEntries: [FuelEntry] = [] | |||||
| // | |||||
| // for fuelEntry in fuelEntries { | |||||
| // let updatedFuelEntry = try await { () async throws -> FuelEntry in | |||||
| // var updatedFuelEntry = fuelEntry | |||||
| // | |||||
| // if let imageData = updatedFuelEntry.imageData { | |||||
| // let imageFilename = "\(updatedFuelEntry.id!).png" | |||||
| // let tempImageURL = URL(fileURLWithPath: directory + imageFilename) | |||||
| // try await imageData.write(to: tempImageURL) | |||||
| // updatedFuelEntry.image = tempImageURL.absoluteString | |||||
| // } | |||||
| // | |||||
| // do { | |||||
| // _ = try await updatedFuelEntry.save(on: req.db) | |||||
| // return updatedFuelEntry | |||||
| // } catch { | |||||
| // throw Abort(.internalServerError, reason: "Error saving FuelEntry: \(error)") | |||||
| // } | |||||
| // }() | |||||
| // | |||||
| // updatedFuelEntries.append(updatedFuelEntry) | |||||
| // } | |||||
| // | |||||
| // return updatedFuelEntries | |||||
| // } | |||||
| func delete(req: Request) async throws -> HTTPStatus { | func delete(req: Request) async throws -> HTTPStatus { | ||||
| guard let fuelEntry = try await FuelEntry.find(req.parameters.get("fuelEntryID"), on: req.db) else { | guard let fuelEntry = try await FuelEntry.find(req.parameters.get("fuelEntryID"), on: req.db) else { | ||||
| throw Abort(.notFound) | throw Abort(.notFound) | ||||
| @@ -1,6 +1,6 @@ | |||||
| // | // | ||||
| // File.swift | // File.swift | ||||
| // | |||||
| // | |||||
| // | // | ||||
| // Created by Bill Ryckman on 4/26/23. | // Created by Bill Ryckman on 4/26/23. | ||||
| // | // | ||||
| @@ -26,43 +26,59 @@ struct CreateFuelEntry: AsyncMigration { | |||||
| .field("is_override", .bool) | .field("is_override", .bool) | ||||
| .create() | .create() | ||||
| } | } | ||||
| func revert(on database: Database) async throws { | func revert(on database: Database) async throws { | ||||
| try await database.schema("fuel_entries").delete() | try await database.schema("fuel_entries").delete() | ||||
| } | } | ||||
| } | } | ||||
| struct AddLatitudeAndLongitudeAndRemoveGpsLocationAndImage: AsyncMigration { | struct AddLatitudeAndLongitudeAndRemoveGpsLocationAndImage: AsyncMigration { | ||||
| func prepare(on database: Database) async throws { | |||||
| try await database.schema("fuel_entries") | |||||
| .field("latitude", .double) | |||||
| .field("longitude", .double) | |||||
| .deleteField("gps_location") | |||||
| .deleteField("image") | |||||
| .update() | |||||
| } | |||||
| func revert(on database: Database) async throws { | |||||
| try await database.schema("fuel_entries") | |||||
| .deleteField("latitude") | |||||
| .deleteField("longitude") | |||||
| .field("gps_location", .string) | |||||
| .field("image", .string) | |||||
| .update() | |||||
| } | |||||
| func prepare(on database: Database) async throws { | |||||
| try await database.schema("fuel_entries") | |||||
| .field("latitude", .double) | |||||
| .field("longitude", .double) | |||||
| .deleteField("gps_location") | |||||
| .deleteField("image") | |||||
| .update() | |||||
| } | |||||
| func revert(on database: Database) async throws { | |||||
| try await database.schema("fuel_entries") | |||||
| .deleteField("latitude") | |||||
| .deleteField("longitude") | |||||
| .field("gps_location", .string) | |||||
| .field("image", .string) | |||||
| .update() | |||||
| } | |||||
| } | } | ||||
| struct AddImageBackIn: AsyncMigration { | struct AddImageBackIn: AsyncMigration { | ||||
| func prepare(on database: Database) async throws { | |||||
| try await database.schema("fuel_entries") | |||||
| .field("image", .string) | |||||
| .update() | |||||
| } | |||||
| func prepare(on database: Database) async throws { | |||||
| try await database.schema("fuel_entries") | |||||
| .field("image", .string) | |||||
| .update() | |||||
| } | |||||
| func revert(on database: Database) async throws { | |||||
| try await database.schema("fuel_entries") | |||||
| .deleteField("image") | |||||
| .update() | |||||
| } | |||||
| } | |||||
| func revert(on database: Database) async throws { | |||||
| try await database.schema("fuel_entries") | |||||
| .deleteField("image") | |||||
| .update() | |||||
| } | |||||
| struct StoreImageDataInDatabase: AsyncMigration { | |||||
| func prepare(on database: Database) async throws { | |||||
| try await database.schema("fuel_entries") | |||||
| .deleteField("image") | |||||
| .field("image", .data) | |||||
| .update() | |||||
| } | |||||
| func revert(on database: Database) async throws { | |||||
| try await database.schema("fuel_entries") | |||||
| .deleteField("image") | |||||
| .field("image", .string) | |||||
| .update() | |||||
| } | |||||
| } | } | ||||
| @@ -27,7 +27,7 @@ final class FuelEntry: Model, Content { | |||||
| var longitude: Double | var longitude: Double | ||||
| @Field(key: "image") | @Field(key: "image") | ||||
| var image: String? | |||||
| var image: Data? | |||||
| @Field(key: "product") | @Field(key: "product") | ||||
| var product: String | var product: String | ||||
| @@ -53,11 +53,11 @@ final class FuelEntry: Model, Content { | |||||
| @Field(key: "is_override") | @Field(key: "is_override") | ||||
| var isOverride: Bool | var isOverride: Bool | ||||
| var imageData: Data? | |||||
| // var imageData: Data? | |||||
| init() {} | init() {} | ||||
| init(id: UUID? = nil, timestamp: Date, userID: String, latitude: Double, longitude: Double, image: String?, product: String, make: String, model: String, serialNumber: String, tankID: String, fuelAmount: Double, fuelType: String, isOverride: Bool, imageData: Data?) { | |||||
| init(id: UUID? = nil, timestamp: Date, userID: String, latitude: Double, longitude: Double, image: Data?, product: String, make: String, model: String, serialNumber: String, tankID: String, fuelAmount: Double, fuelType: String, isOverride: Bool) { //imageData: Data? | |||||
| self.id = id | self.id = id | ||||
| self.timestamp = timestamp | self.timestamp = timestamp | ||||
| self.userID = userID | self.userID = userID | ||||
| @@ -72,6 +72,6 @@ final class FuelEntry: Model, Content { | |||||
| self.fuelAmount = fuelAmount | self.fuelAmount = fuelAmount | ||||
| self.fuelType = fuelType | self.fuelType = fuelType | ||||
| self.isOverride = isOverride | self.isOverride = isOverride | ||||
| self.imageData = imageData | |||||
| // self.imageData = imageData | |||||
| } | } | ||||
| } | } | ||||
| @@ -14,6 +14,7 @@ public func configure(_ app: Application) async throws { | |||||
| app.migrations.add(CreateFuelEntry()) | app.migrations.add(CreateFuelEntry()) | ||||
| app.migrations.add(AddLatitudeAndLongitudeAndRemoveGpsLocationAndImage()) | app.migrations.add(AddLatitudeAndLongitudeAndRemoveGpsLocationAndImage()) | ||||
| app.migrations.add(AddImageBackIn()) | app.migrations.add(AddImageBackIn()) | ||||
| app.migrations.add(StoreImageDataInDatabase()) | |||||
| try await app.autoMigrate().get() | try await app.autoMigrate().get() | ||||
| // register routes | // register routes | ||||
| @@ -23,9 +23,9 @@ func routes(_ app: Application) throws { | |||||
| try await fuelEntryV2Controller.index(req: req) | try await fuelEntryV2Controller.index(req: req) | ||||
| } | } | ||||
| v2.get("fuel-entries", "with-images") {req in | |||||
| try await fuelEntryV2Controller.getAllEntriesWithImages(req: req) | |||||
| } | |||||
| // v2.get("fuel-entries", "with-images") {req in | |||||
| // try await fuelEntryV2Controller.getAllEntriesWithImages(req: req) | |||||
| // } | |||||
| v2.post("fuel-entries") {req in | v2.post("fuel-entries") {req in | ||||
| try await fuelEntryV2Controller.create(req: req) | try await fuelEntryV2Controller.create(req: req) | ||||