Merge branch '33-merge-development' into 'main'

Resolve "Merge Development"

Closes #33

See merge request thschleicher/interaktive-systeme!13
This commit is contained in:
jastornig 2023-12-08 15:27:50 +00:00
commit d0db67522e
4 changed files with 206 additions and 2 deletions

View file

@ -1,5 +1,21 @@
import { useEffect } from 'react';
import { Text } from 'react-native'; import { Text } from 'react-native';
import { executeQuery, initDatabase, addCategory } from '../../../services/database';
export default function Page() { export default function Page() {
useEffect(() => {
initDatabase().then();
addCategory("Test Category 2", "FFFFFF", "budget").then();
executeQuery("SELECT * FROM category").then((res) => {
console.log(res);
});;
//deleteDatabase();
});
return <Text>Budget Page</Text>; return <Text>Budget Page</Text>;
} }

59
package-lock.json generated
View file

@ -16,6 +16,7 @@
"expo-router": "^2.0.0", "expo-router": "^2.0.0",
"expo-secure-store": "~12.3.1", "expo-secure-store": "~12.3.1",
"expo-splash-screen": "~0.20.5", "expo-splash-screen": "~0.20.5",
"expo-sqlite": "~11.3.3",
"expo-status-bar": "~1.6.0", "expo-status-bar": "~1.6.0",
"expo-system-ui": "~2.4.0", "expo-system-ui": "~2.4.0",
"expo-web-browser": "~12.3.2", "expo-web-browser": "~12.3.2",
@ -25,6 +26,7 @@
"react-native-gesture-handler": "~2.12.0", "react-native-gesture-handler": "~2.12.0",
"react-native-safe-area-context": "4.6.3", "react-native-safe-area-context": "4.6.3",
"react-native-screens": "~3.22.0", "react-native-screens": "~3.22.0",
"react-native-uuid": "^2.0.1",
"react-native-web": "~0.19.6" "react-native-web": "~0.19.6"
}, },
"devDependencies": { "devDependencies": {
@ -3200,6 +3202,18 @@
"resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-13.0.0.tgz", "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-13.0.0.tgz",
"integrity": "sha512-TI+l71+5aSKnShYclFa14Kum+hQMZ86b95SH6tQUG3qZEmLTarvWpKwqtTwQKqvlJSJrpFiSFu3eCuZokY6zWA==" "integrity": "sha512-TI+l71+5aSKnShYclFa14Kum+hQMZ86b95SH6tQUG3qZEmLTarvWpKwqtTwQKqvlJSJrpFiSFu3eCuZokY6zWA=="
}, },
"node_modules/@expo/websql": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@expo/websql/-/websql-1.0.1.tgz",
"integrity": "sha512-H9/t1V7XXyKC343FJz/LwaVBfDhs6IqhDtSYWpt8LNSQDVjf5NvVJLc5wp+KCpRidZx8+0+YeHJN45HOXmqjFA==",
"dependencies": {
"argsarray": "^0.0.1",
"immediate": "^3.2.2",
"noop-fn": "^1.0.0",
"pouchdb-collections": "^1.0.1",
"tiny-queue": "^0.2.1"
}
},
"node_modules/@expo/xcpretty": { "node_modules/@expo/xcpretty": {
"version": "4.2.2", "version": "4.2.2",
"resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.2.2.tgz", "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.2.2.tgz",
@ -6836,6 +6850,11 @@
"sprintf-js": "~1.0.2" "sprintf-js": "~1.0.2"
} }
}, },
"node_modules/argsarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz",
"integrity": "sha512-u96dg2GcAKtpTrBdDoFIM7PjcBA+6rSP0OR94MOReNRyUECL6MtQt5XXmRr4qrftYaef9+l5hcpO5te7sML1Cg=="
},
"node_modules/array-union": { "node_modules/array-union": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@ -9028,6 +9047,17 @@
"expo": "*" "expo": "*"
} }
}, },
"node_modules/expo-sqlite": {
"version": "11.3.3",
"resolved": "https://registry.npmjs.org/expo-sqlite/-/expo-sqlite-11.3.3.tgz",
"integrity": "sha512-73n+mhwi5mO28oVVrDGYcjy28XeUjNtpXVPtEmc+sr/NQ0hKlkIf2PD3/gKsyNuI8O/twNCZxsAQdM32yHGr8A==",
"dependencies": {
"@expo/websql": "^1.0.1"
},
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-status-bar": { "node_modules/expo-status-bar": {
"version": "1.6.0", "version": "1.6.0",
"resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-1.6.0.tgz", "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-1.6.0.tgz",
@ -9861,6 +9891,11 @@
"node": ">=14.0.0" "node": ">=14.0.0"
} }
}, },
"node_modules/immediate": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz",
"integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q=="
},
"node_modules/import-fresh": { "node_modules/import-fresh": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
@ -14505,6 +14540,11 @@
"url": "https://github.com/sponsors/antelle" "url": "https://github.com/sponsors/antelle"
} }
}, },
"node_modules/noop-fn": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/noop-fn/-/noop-fn-1.0.0.tgz",
"integrity": "sha512-pQ8vODlgXt2e7A3mIbFDlizkr46r75V+BJxVAyat8Jl7YmI513gG5cfyRL0FedKraoZ+VAouI1h4/IWpus5pcQ=="
},
"node_modules/normalize-path": { "node_modules/normalize-path": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@ -15170,6 +15210,11 @@
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
}, },
"node_modules/pouchdb-collections": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pouchdb-collections/-/pouchdb-collections-1.0.1.tgz",
"integrity": "sha512-31db6JRg4+4D5Yzc2nqsRqsA2oOkZS8DpFav3jf/qVNBxusKa2ClkEIZ2bJNpaDbMfWtnuSq59p6Bn+CipPMdg=="
},
"node_modules/prepend-http": { "node_modules/prepend-http": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
@ -15676,6 +15721,15 @@
"react-native": "*" "react-native": "*"
} }
}, },
"node_modules/react-native-uuid": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/react-native-uuid/-/react-native-uuid-2.0.1.tgz",
"integrity": "sha512-cptnoIbL53GTCrWlb/+jrDC6tvb7ypIyzbXNJcpR3Vab0mkeaaVd5qnB3f0whXYzS+SMoSQLcUUB0gEWqkPC0g==",
"engines": {
"node": ">=10.0.0",
"npm": ">=6.0.0"
}
},
"node_modules/react-native-web": { "node_modules/react-native-web": {
"version": "0.19.9", "version": "0.19.9",
"resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.19.9.tgz", "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.19.9.tgz",
@ -16896,6 +16950,11 @@
"xtend": "~4.0.1" "xtend": "~4.0.1"
} }
}, },
"node_modules/tiny-queue": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/tiny-queue/-/tiny-queue-0.2.1.tgz",
"integrity": "sha512-EijGsv7kzd9I9g0ByCl6h42BWNGUZrlCSejfrb3AKeHC33SGbASu1VDf5O3rRiiUOhAC9CHdZxFPbZu0HmR70A=="
},
"node_modules/tmp": { "node_modules/tmp": {
"version": "0.0.33", "version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",

View file

@ -24,7 +24,9 @@
"expo-font": "~11.4.0", "expo-font": "~11.4.0",
"expo-linking": "~5.0.2", "expo-linking": "~5.0.2",
"expo-router": "^2.0.0", "expo-router": "^2.0.0",
"expo-secure-store": "~12.3.1",
"expo-splash-screen": "~0.20.5", "expo-splash-screen": "~0.20.5",
"expo-sqlite": "~11.3.3",
"expo-status-bar": "~1.6.0", "expo-status-bar": "~1.6.0",
"expo-system-ui": "~2.4.0", "expo-system-ui": "~2.4.0",
"expo-web-browser": "~12.3.2", "expo-web-browser": "~12.3.2",
@ -34,8 +36,8 @@
"react-native-gesture-handler": "~2.12.0", "react-native-gesture-handler": "~2.12.0",
"react-native-safe-area-context": "4.6.3", "react-native-safe-area-context": "4.6.3",
"react-native-screens": "~3.22.0", "react-native-screens": "~3.22.0",
"react-native-web": "~0.19.6", "react-native-uuid": "^2.0.1",
"expo-secure-store": "~12.3.1" "react-native-web": "~0.19.6"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.20.0", "@babel/core": "^7.20.0",

127
services/database.ts Normal file
View file

@ -0,0 +1,127 @@
//created by thschleicher
import * as SQLite from "expo-sqlite";
import uuid from "react-native-uuid";
import { Query } from "expo-sqlite";
const db = SQLite.openDatabase("interactive_systeme.db");
export const initDatabase = async () => {
try {
await db.transactionAsync(async (tx: SQLite.SQLTransactionAsync) => {
await tx.executeSqlAsync(
"CREATE TABLE IF NOT EXISTS category (guid VARCHAR(36) PRIMARY KEY, name TEXT, color TEXT, type TEXT);"
);
await tx.executeSqlAsync(
"CREATE TABLE IF NOT EXISTS expense (guid VARCHAR(36) PRIMARY KEY, name TEXT, category_guid VARCHAR(36), datetime DATETIME, amount DOUBLE, FOREIGN KEY (category_guid) REFERENCES category(guid));"
);
console.log("Successfully initialized Tables!");
});
} catch (error) {
console.log("Error initializing the Tables!");
throw (error);
}
};
export const addCategory = async (name: string, color: string, type: string) => {
//needs user input validation for type and color (should be validated by this function)
const UUID = uuid.v4();
try {
await db.transactionAsync(async (tx) => {
await tx.executeSqlAsync("INSERT INTO category (guid, name, color, type) VALUES (?, ?, ?, ?);",
[UUID.toString(), name, color, type]
);
});
console.log("Category added successfully!");
} catch (error) {
console.log("Error adding category: ", error);
throw error;
}
}
export const addExpense = async (name: string, category_guid: string,datetime: string, amount: number) => {
//needs user input validation for type and color (should be validated by this function)
const expenseUUID = uuid.v4();
try {
await db.transactionAsync(async (tx) => {
await tx.executeSqlAsync("INSERT INTO expense (guid, name, category_guid, datetime, amount) VALUES (?, ?, ?, ?, ?);", [expenseUUID.toString(), name, category_guid, datetime, amount]
);
});
console.log("Expense added successfully!");
} catch (error) {
console.log("Error adding expense: ", error);
throw error;
}
};
export const deleteCategory = async (guid: string) => {
try {
await db.transactionAsync(async (tx: SQLite.SQLTransactionAsync) => {
await tx.executeSqlAsync("DELETE FROM category WHERE guid = ?;", [guid]);
});
} catch(error) {
console.log("Error deleting category: ", error);
throw error;
}
}
export const deleteExpense = async (guid: string) => {
try {
await db.transactionAsync(async (tx: SQLite.SQLTransactionAsync) => {
await tx.executeSqlAsync("DELETE FROM expense WHERE guid = ?;", [guid]);
});
} catch(error) {
console.log("Error deleting expense: ", error);
throw error;
}
}
export const executeQuery = async (query: string) => {
const sqliteQuary: Query[] = [{sql: query, args: []}];
const result = await runQuery(sqliteQuary);
if("rows" in result[0]) {
return result[0]["rows"];
}
console.error("Query could not be executed!");
};
export const deleteDatabase = () => {
closeDatabase().then(() => {
try {
db.deleteAsync()
} catch (error) {
console.log("Error deleting the Database: ", error);
throw error;
}
});
console.log("Database Deleted!")
}
const runQuery = async (query: Query[]) => {
try {
return await db.execAsync(query, true);
} catch (error) {
console.log("Error running Quary: ", error);
throw(error);
}
};
const closeDatabase = async () => {
try {
db.closeAsync();
} catch (error) {
console.log("Error, cant close database: ", error);
throw error;
}
}