Created
August 17, 2022 17:30
-
-
Save vmic2002/68bdfb71a55a1410ba0e708a81b24af1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// DBHelper.swift | |
// GroupAccounting | |
// | |
// Created by Victor Micha on 8/17/22. | |
// | |
import Foundation | |
//variables | |
let ASTRA_DB_ID = "REPLACE_ME" | |
let ASTRA_DB_TOKEN = "REPLACE_ME" | |
let ASTRA_DB_REGION = "REPLACE_ME" | |
let ASTRA_DB_KEYSPACENAME = "REPLACE_ME" | |
//model | |
struct UserInfo : Codable { | |
let userName : String | |
let password : String | |
} | |
struct Password : Codable { | |
let password : String | |
} | |
//backend functions | |
func deleteDoc(docID:String, collection:String) async throws { | |
let urlRequest = getURLRequest(httpMethod: "DELETE", endURL: "/namespaces/\(ASTRA_DB_KEYSPACENAME)/collections/\(collection)/\(docID)") | |
let (_, response) = try await URLSession.shared.data(for: urlRequest) | |
guard let response = response as? HTTPURLResponse, | |
response.statusCode == 204 else { | |
//successful DELETE using DOC API has status code of 204 | |
print("Response: \(response)") | |
print("Error: could not DELETE doc: \(docID)") | |
return | |
} | |
print("No error occurred while DELETING doc \(docID)") | |
} | |
func printUserInfoDict(userName:String) async throws { | |
let dict = try await getUserInfo(userName: userName) | |
if (dict.count==0) { | |
print("No account for \(userName)") | |
} else { | |
//usernames are unique so dict.count must be equal 1 | |
let userInfo = dict[dict.startIndex].value | |
let docID = dict[dict.startIndex].key | |
print("Username: \(userInfo.userName)") | |
print("Password: \(userInfo.password)") | |
print("DocID: \(docID)") | |
} | |
} | |
func getUserInfo(userName:String) async throws -> [String:UserInfo] { | |
let dataString = try await getRequest(endURL: "/namespaces/\(ASTRA_DB_KEYSPACENAME)/collections/userInfo?where={\"userName\":{\"$eq\":\"\(userName)\"}}&page-size=1") | |
let (formattedData, _) = processDataString(dataString: dataString) | |
if let jsonData = formattedData.data(using: .utf8){ | |
do{ | |
let userInfoDict = try JSONDecoder().decode([String:UserInfo].self, from: jsonData) | |
//userInfoDict is a dictionary of [String:UserInfo] or [DocID:UserInfo] | |
//if userInfoDict.count==0, there is no account for userName | |
//if userInfoDict.count==1, there is an account for userName | |
return userInfoDict | |
} catch { | |
print("Could not decode into a dictionary") | |
return [String:UserInfo]() | |
} | |
} else { | |
print("Could not convert string to Data") | |
return [String:UserInfo]() | |
} | |
} | |
func processDataString(dataString:String)->(String, String){ | |
var dataString = dataString | |
/* | |
JSON dataString is of the form | |
{“data”: | |
{ | |
“docID”:Order, | |
“docID”:Order | |
} | |
} | |
OR (if there are more docs than <page-size> or <20>) | |
{"pageState":"JDZjN2Y5MGQ5LWYyZGItNGRkNS05Mzk3LTZiNDE5NzYzNGMwZQDwf_____B_____","data":{ | |
“docID”:Order, | |
“docID”:Order | |
} | |
} | |
*/ | |
var pageState = "" | |
let y = 64//length of page-state | |
if (dataString[dataString.index(dataString.startIndex, offsetBy: 2)]=="p"){ | |
pageState = String(dataString[dataString.index(dataString.startIndex, offsetBy: 14)...dataString.index(dataString.startIndex, offsetBy: 14+y-1)]) | |
} | |
//need to clean up/proccess dataString | |
var indx = dataString.startIndex//arbitrary, val is changed in if/else statement | |
if (dataString[dataString.index(dataString.startIndex, offsetBy: 2)]=="p"){ | |
//there is page state | |
//length of {"pageState":"JDZjN2Y5MGQ5LWYyZGItNGRkNS05Mzk3LTZiNDE5NzYzNGMwZQDwf_____B_____","data": | |
//is 87 which is equal to 23+y | |
indx = dataString.index(dataString.startIndex, offsetBy: 23+y) | |
} else { | |
//there is no page state | |
//length of {“data”: is 8 | |
indx = dataString.index(dataString.startIndex, offsetBy: 8) | |
} | |
let x = dataString.startIndex..<indx | |
dataString.removeSubrange(x) | |
dataString.removeLast()//to remove last } | |
//print("dataString: \(dataString)") | |
/* | |
by now dataString is of form: | |
{ | |
“docID”:Order, | |
“docID”:Order | |
} or {"docID":UserInfo} | |
*/ | |
return (dataString, pageState) | |
} | |
func getRequest(endURL:String) async throws -> String { | |
let urlRequest = getURLRequest(httpMethod: "GET", endURL: endURL) | |
let (data, response) = try await URLSession.shared.data(for: urlRequest) | |
guard let response = response as? HTTPURLResponse, | |
response.statusCode == 200 else { | |
//successful GET request using the Document API has status code 200 | |
print("Response: \(response)") | |
print("Error occured during GET request") | |
return"" | |
} | |
if response.mimeType == "application/json", | |
let dataString = String(data:data, encoding: .utf8){ | |
print("got data: \(dataString)") | |
/* | |
dataString is of the form: | |
{"data":{"documentId":UserInfo}} | |
*/ | |
return dataString | |
} | |
print("Data could not be converted into a String") | |
return "" | |
} | |
func changePassword(docID:String, newPassword:String) async throws { | |
let encoder = JSONEncoder() | |
guard let uploadData = try? encoder.encode(Password(password: newPassword)) else { | |
print("Could not convert struct to JSON") | |
return | |
} | |
let urlRequest = getURLRequest(httpMethod: "PATCH", endURL: "/namespaces/\(ASTRA_DB_KEYSPACENAME)/collections/userInfo/\(docID)") | |
let (data, response) = try await URLSession.shared.upload(for: urlRequest, from: uploadData) | |
guard let response = response as? HTTPURLResponse, | |
response.statusCode == 200 else { | |
//successful PATCH to astra using the Document API has status code 200 | |
print("Response: \(response)") | |
print("Could not PATCH to collection userInfo") | |
return | |
} | |
if response.mimeType == "application/json", | |
let dataString = String(data: data, encoding: .utf8){ | |
print("got data: \(dataString)") | |
print("PATCH to collection userInfo is successful!") | |
/* | |
dataString is of the form: | |
{"documentId":"..."} | |
*/ | |
return | |
} | |
print("Data could not be converted to String") | |
} | |
func postUserInfo(userInfo:UserInfo) async throws { | |
let encoder = JSONEncoder() | |
guard let uploadData = try? encoder.encode(userInfo) else { | |
print("Could not convert struct to JSON") | |
return | |
} | |
let urlRequest = getURLRequest(httpMethod: "POST", endURL: "/namespaces/\(ASTRA_DB_KEYSPACENAME)/collections/userInfo") | |
let (data, response) = try await URLSession.shared.upload(for: urlRequest, from: uploadData) | |
guard let response = response as? HTTPURLResponse, | |
response.statusCode == 201 else { | |
//successful POST to astra using the Document API has status code 201 | |
print("Response: \(response)") | |
print("Could not POST to collection userInfo") | |
return | |
} | |
if response.mimeType == "application/json", | |
let dataString = String(data: data, encoding: .utf8){ | |
print("got data: \(dataString)") | |
print("POST to collection userInfo is successful!") | |
/* | |
dataString is of the form: | |
{"documentId":"..."} | |
*/ | |
return | |
} | |
print("Data could not be converted to String") | |
} | |
//this function is called everytime a HTTP request is performed to connect to ASTRA | |
func getURLRequest(httpMethod:String, endURL:String) -> URLRequest { | |
let str = "https://"+ASTRA_DB_ID+"-"+ASTRA_DB_REGION+".apps.astra.datastax.com/api/rest/v2"+endURL | |
let encodedStr = str.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)! | |
let url = URL.init(string:encodedStr)! | |
var urlRequest = URLRequest(url: url) | |
urlRequest.httpMethod = httpMethod //POST, PATCH, DELETE, GET | |
if (httpMethod == "POST") { | |
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") | |
} | |
urlRequest.setValue("application/json", forHTTPHeaderField: "accept") | |
urlRequest.setValue(ASTRA_DB_TOKEN, forHTTPHeaderField: "X-Cassandra-Token") | |
return urlRequest | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment