5 Коміти aac87425bb ... ba1e23cda2

Автор SHA1 Опис Дата
  kunickyd ba1e23cda2 improve db init 3 роки тому
  kunickyd 0d05e7b3e3 transfer history impl 3 роки тому
  kunickyd b7ff7edc53 ignore db folder 3 роки тому
  kunickyd 537f8facf1 get transfers 3 роки тому
  kunickyd a0b96e84bb add sqlite3 3 роки тому
3 змінених файлів з 120 додано та 12 видалено
  1. 3 1
      .gitignore
  2. 114 10
      app.ts
  3. 3 1
      package.json

+ 3 - 1
.gitignore

@@ -131,4 +131,6 @@ package-lock.json
 .vs
 
 #Build folder
-build
+build
+
+data

+ 114 - 10
app.ts

@@ -1,5 +1,5 @@
 import 'dotenv/config'
-import grpc from "grpc" 
+import grpc from "grpc"
 import express from "express"
 import bodyParser from "body-parser"
 import basicAuth from "express-basic-auth"
@@ -10,7 +10,9 @@ import {
 import { queries } from 'iroha-helpers'
 import util from 'util'
 import { exec } from 'child_process'
-import  cors  from 'cors'
+import cors from 'cors'
+import * as sql from 'sqlite3'
+import fs from 'fs'
 
 const app = express();
 app.use(bodyParser.json());
@@ -18,7 +20,7 @@ app.use(bodyParser.json());
 //TODO is cors package necesary? basic middleware could suffice 
 app.use(cors()); //TODO: set only safe origins
 app.use(basicAuth({
-    users: { admin: 'superPasswd' }    
+    users: { admin: 'superPasswd' }
 }));
 
 
@@ -35,10 +37,75 @@ const CHAIN4ALL_RASTER_CLIP_SCRIPT_PATH = process.env.CHAIN4ALL_RASTER_CLIP_SCRI
 const CHAIN4ALL_SERVICE_PORT = process.env.CHAIN4ALL_SERVICE_PORT || 3000;
 const PRICE_MODIFIER: number = parseFloat(process.env.PRICE_MODIFIER || "0.5");
 
+const DB_FILE_NAME: string = "data/transfers.db";
+
 app.get("/", (req, res) => {
     res.send("Chain4All Blockchain service");
 });
 
+app.get("/transfers/:userId", async (req, res, next) => {
+    let db = await getDbConnection();
+
+    db.all(
+        "SELECT hash " +
+        "FROM transfers " +
+        "WHERE user=? " +
+        "ORDER BY id DESC " +
+        "LIMIT 10;",
+        [req.params.userId],
+        (err, rows) => {
+            if (err) {
+                next(err);
+                return;
+            }
+                        
+            res.send(rows);
+        }
+    );
+
+    db.close();
+});
+
+app.post("/transfer", async (req, res, next) => {
+    try {
+        if (!req.body) {
+            res.status(400);
+            throw Error(JSON.stringify({ error: { name: "Error, request has no body!" } }));
+        }
+
+        if (!req.body.txHash) {
+            res.status(400);
+            throw Error(JSON.stringify({ error: { name: "Error, request body has no \"txHash\" property!" } }));
+        }
+
+        if (!req.body.user) {
+            res.status(400);
+            throw Error(JSON.stringify({ error: { name: "Error, request body has no \"user\" property!" } }));
+        }
+
+        let db = await getDbConnection();
+
+        db.run(
+            "INSERT INTO transfers (hash, user)" +
+            "VALUES (?, ?);",
+            [req.body.txHash, req.body.user],
+            (err) => {
+                if (err) {
+                    next(err);
+                    return;
+                }
+                res.status(201);
+                res.send();
+            }
+        );
+
+        db.close();
+    }
+    catch (err) {
+        next(err);
+    }
+});
+
 app.post("/price", (req, res) => { //add caching of same requests    
     if (req.body && req.body.area) {
         res.send({ price: getPrice(req.body.area) });
@@ -73,25 +140,56 @@ app.post("/buy", async (req, res, next) => {
 
         let extent: number[] = JSON.parse(txDetail.description).extent as number[];
         let dataFileId: string = Date.now().toString();
-        
+
         let dataCommand = CHAIN4ALL_RASTER_CLIP_SCRIPT_PATH + ' ' + extent[0] + ' ' + extent[1] + ' ' + extent[2] + ' ' + extent[3] + ' ' + dataFileId;
         console.debug(dataCommand);
 
         const { stdout, stderr } = await asyncExec(dataCommand);
-        
+
         console.debug(stdout);
 
-        if(stderr){
+        if (stderr) {
             console.warn(stderr);
         }
 
-        res.send({dataUrl: "https://gis.lesprojekt.cz/chain4all/raster_" + dataFileId + ".tif"});
+        res.send({ dataUrl: "https://gis.lesprojekt.cz/chain4all/raster_" + dataFileId + ".tif" });
     }
     catch (err) {
         next(err);
     }
 });
 
+function getDbConnection(): sql.Database {
+
+    return new sql.Database(DB_FILE_NAME);
+}
+
+function initDatabase(): Promise<void>{
+    return new Promise<void>((resolve, reject) => {
+        if(!fs.existsSync("./data")){
+            fs.mkdirSync("data");
+        };
+        
+        let db = getDbConnection();
+
+        db.run(
+            "CREATE TABLE IF NOT EXISTS transfers( " +
+            "id INTEGER PRIMARY KEY, " +
+            "hash TEXT NOT NULL, " +
+            "user TEXT NOT NULL " +
+            ");",
+            (err) => {
+                if (err) {
+                    reject(err);
+                }
+                else{
+                    resolve();
+                }
+            }
+        );
+    });
+}
+
 async function getTransactionDetail(txHash: string, user: string) {
     let quer: any = await queries.getAccountTransactions({
         privateKey: IROHA_ADMIN_PRIV,
@@ -116,7 +214,7 @@ async function getTransactionDetail(txHash: string, user: string) {
     return quer.transactionsList[0].payload.reducedPayload.commandsList[0].transferAsset;
 }
 
-function getPrice(area: number) : number {
+function getPrice(area: number): number {
     return area * PRICE_MODIFIER;
 }
 
@@ -128,6 +226,12 @@ function errorMiddleware(err: any, req: any, res: any, next: any): void { //TODO
 
 app.use(errorMiddleware);
 
-app.listen(CHAIN4ALL_SERVICE_PORT, () => {
-    console.log(`Listening at http://localhost:${CHAIN4ALL_SERVICE_PORT}`)
+app.listen(CHAIN4ALL_SERVICE_PORT,async () => {
+    try{
+        await initDatabase();
+        console.log(`Listening at http://localhost:${CHAIN4ALL_SERVICE_PORT}`);
+    }catch(err){
+        console.error("Cannot start service!");
+        console.error(err);
+    }    
 });

+ 3 - 1
package.json

@@ -17,7 +17,8 @@
     "express": "^4.17.2",
     "express-basic-auth": "^1.2.1",
     "grpc": "^1.24.11",
-    "iroha-helpers": "^1.3.0"
+    "iroha-helpers": "^1.3.0",
+    "sqlite3": "^5.0.2"
   },
   "devDependencies": {
     "@tsconfig/node10": "^1.0.8",
@@ -25,6 +26,7 @@
     "@types/cors": "^2.8.12",
     "@types/express": "^4.17.13",
     "@types/node": "^17.0.16",
+    "@types/sqlite3": "^3.1.8",
     "nodemon": "^2.0.15",
     "ts-node": "^10.5.0",
     "typescript": "^4.5.5"