From ac5a9ec31add0e72534808e41a220b367e556ae6 Mon Sep 17 00:00:00 2001 From: Immanuel Onyeka Date: Fri, 18 Nov 2022 15:35:10 -0500 Subject: [PATCH] Use zero vector for missing values instead of null Null makes missing values harder to convert to json using the Scan operation. 0 and '' will be used instead to be type consistent. --- migrations/0_29092022_create_main_tables.sql | 29 +++--- migrations/seed.sql | 36 +++---- skouter.go | 98 +++++++++++++------- 3 files changed, 97 insertions(+), 66 deletions(-) diff --git a/migrations/0_29092022_create_main_tables.sql b/migrations/0_29092022_create_main_tables.sql index 99c800f..08d383d 100644 --- a/migrations/0_29092022_create_main_tables.sql +++ b/migrations/0_29092022_create_main_tables.sql @@ -7,7 +7,7 @@ CREATE TABLE comparison ( CREATE TABLE branch ( id INT AUTO_INCREMENT, - type ENUM('NMLS', 'FSRA'), + type ENUM('NMLS', 'FSRA') NOT NULL, num VARCHAR(40) NOT NULL, PRIMARY KEY (id) ); @@ -50,8 +50,8 @@ CREATE TABLE license ( * Types with branch_id and user_id values of null will be general cases. */ CREATE TABLE loan_type ( id INT AUTO_INCREMENT, - branch_id INT, - user_id INT, + branch_id INT NOT NULL, + user_id INT NOT NULL, name VARCHAR(30) NOT NULL, FOREIGN KEY (branch_id) REFERENCES branch(id), FOREIGN KEY (user_id) REFERENCES user(id), @@ -60,9 +60,9 @@ CREATE TABLE loan_type ( CREATE TABLE borrower ( id INT AUTO_INCREMENT, - credit_score SMALLINT, - monthly_income INT, - num TINYINT, /* Number of people borrowing. */ + credit_score SMALLINT NOT NULL, + monthly_income INT NOT NULL, + num TINYINT NOT NULL, /* Number of people borrowing. */ PRIMARY KEY (`id`) ); @@ -113,18 +113,19 @@ CREATE TABLE fee ( ); /* Templates to be reused by users or branches. Either user_id or branch_id must - * be non-null. */ + * be non-null.*/ CREATE TABLE fee_template ( id INT AUTO_INCREMENT, - user_id INT, - branch_id INT, - amount INT, - perc SMALLINT, /* Percentage of sale price instead of amount */ + user_id INT NOT NULL, + branch_id INT NOT NULL, + amount INT NOT NULL, + perc SMALLINT NOT NULL, + /* Percentage of sale price instead of amount */ type ENUM('Goverment', 'Title', 'Required', 'Lender', 'Other'), - notes VARCHAR(255), - name VARCHAR(30), + notes VARCHAR(255) NOT NULL, + name VARCHAR(30) NOT NULL, /* Group heading shown in report */ - category VARCHAR(60), + category VARCHAR(60) NOT NULL, auto BOOLEAN NOT NULL, /* If fee should be automatically applied */ PRIMARY KEY (`id`), diff --git a/migrations/seed.sql b/migrations/seed.sql index 5394a86..a01b6a5 100644 --- a/migrations/seed.sql +++ b/migrations/seed.sql @@ -32,7 +32,7 @@ INSERT IGNORE INTO user ( 'Giant', 'Coltrane', sha2('test123', 256), - null, + 0, 'USA', 'Mortgage Broker', 'unverified@example.com', @@ -75,11 +75,11 @@ INSERT IGNORE INTO loan_type ( ) VALUES ( (SELECT id FROM branch LIMIT 1), - NULL, + 0, 'testType' ), ( - NULL, + 0, (SELECT id FROM user WHERE email="manager@example.com" LIMIT 1), 'manager idea' ); @@ -94,7 +94,7 @@ INSERT IGNORE INTO fee_template ( name ) VALUES ( - NULL, + 0, (SELECT id FROM branch LIMIT 1), 0, 200, @@ -113,7 +113,7 @@ INSERT IGNORE INTO fee_template ( ), ( (SELECT id FROM user WHERE email="test@example.com" LIMIT 1), - NULL, + 0, 9900, 0, "Government", @@ -122,7 +122,7 @@ INSERT IGNORE INTO fee_template ( ), ( (SELECT id FROM user WHERE email="test@example.com" LIMIT 1), - NULL, + 0, 0, 400, 'Lender', @@ -136,27 +136,27 @@ INSERT IGNORE INTO loan_type ( name ) VALUES ( - NULL, - NULL, + 0, + 0, "Conventional" ), ( - NULL, - NULL, + 0, + 0, "FHA" ), ( - NULL, - NULL, + 0, + 0, "VA" ), ( - NULL, - NULL, + 0, + 0, "USDA" ), ( - NULL, + 0, (SELECT id FROM branch LIMIT 1), "Test" ); @@ -192,7 +192,7 @@ INSERT IGNORE INTO estimate ( ( (SELECT id FROM user WHERE email="test@example.com" LIMIT 1), (SELECT id FROM borrower ORDER BY id DESC LIMIT 1), - NULL, + 0, 'Purchase', (SELECT id FROM loan_type WHERE name="Conventional"), 3300000, @@ -209,7 +209,7 @@ INSERT IGNORE INTO estimate ( ( (SELECT id FROM user WHERE email="manager@example.com" LIMIT 1), (SELECT id FROM borrower ORDER BY id DESC LIMIT 1), - NULL, + 0, 'Purchase', (SELECT id FROM loan_type WHERE name="FHA"), 2510000, @@ -226,7 +226,7 @@ INSERT IGNORE INTO estimate ( ( (SELECT id FROM user WHERE email="test@example.com" LIMIT 1), (SELECT id FROM borrower ORDER BY id DESC LIMIT 1), - NULL, + 0, 'Refinance', (SELECT id FROM loan_type WHERE name="USDA"), 8000000, diff --git a/skouter.go b/skouter.go index 07ce163..fdaf59b 100644 --- a/skouter.go +++ b/skouter.go @@ -9,6 +9,7 @@ import ( "database/sql" _ "github.com/go-sql-driver/mysql" "fmt" + "encoding/json" ) type Page struct { @@ -18,23 +19,23 @@ type Page struct { } type LoanType struct { - id int - user sql.NullInt64 - branch sql.NullInt64 - name string + Id int `json:"id"` + User int `json:"user"` + Branch int `json:"branch"` + Name string `json:"name"` } type FeeTemplate struct { - id sql.NullInt64 - user sql.NullInt64 - branch sql.NullInt64 - amount sql.NullInt64 - perc sql.NullInt64 - ftype sql.NullString - notes sql.NullString - name sql.NullString - category sql.NullString - auto bool + Id int + User int + Branch int + Amount int + Perc int + Ftype string + Notes string + Name string + Category string + Auto bool } type Estimate struct { @@ -113,7 +114,7 @@ func getLoanType(db *sql.DB, id int, isUser bool) ([]LoanType, error) { // Should be changed to specify user rows, err := db.Query("SELECT * FROM loan_type WHERE user_id = ? " + - "OR (user_id = NULL AND branch_id = NULL)", id) + "OR (user_id = 0 AND branch_id = 0)", id) if err != nil { return nil, fmt.Errorf("loan_type error: %v", err) @@ -125,9 +126,10 @@ func getLoanType(db *sql.DB, id int, isUser bool) ([]LoanType, error) { var loan LoanType if err := rows.Scan( - &loan.user, - &loan.branch, - &loan.name) + &loan.Id, + &loan.User, + &loan.Branch, + &loan.Name) err != nil { log.Printf("Error occured fetching loan: %v", err) return nil, fmt.Errorf("Error occured fetching loan: %v", err) @@ -136,6 +138,7 @@ func getLoanType(db *sql.DB, id int, isUser bool) ([]LoanType, error) { loans = append(loans, loan) } + log.Printf("The loans: %v", loans) return loans, nil } @@ -155,16 +158,16 @@ func getFees(db *sql.DB, user int) ([]FeeTemplate, error) { var fee FeeTemplate if err := rows.Scan( - &fee.id, - &fee.user, - &fee.branch, - &fee.amount, - &fee.perc, - &fee.ftype, - &fee.notes, - &fee.name, - &fee.category, - &fee.auto) + &fee.Id, + &fee.User, + &fee.Branch, + &fee.Amount, + &fee.Perc, + &fee.Ftype, + &fee.Notes, + &fee.Name, + &fee.Category, + &fee.Auto) err != nil { return nil, fmt.Errorf("The fees %q: %v", user, err) } @@ -179,8 +182,8 @@ func getFees(db *sql.DB, user int) ([]FeeTemplate, error) { func route(w http.ResponseWriter, r *http.Request) { var page Page var args []string - p := r.URL.Path + switch { case r.Method == "GET" && match(p, "/", &args): page = pages[ "home" ] @@ -198,24 +201,51 @@ func route(w http.ResponseWriter, r *http.Request) { page.Render(w) } -func main() { - files := http.FileServer(http.Dir("")) +func api(w http.ResponseWriter, r *http.Request) { + var args []string + // var response string + p := r.URL.Path db, err := sql.Open("mysql", - fmt.Sprintf( "%s:%s@tcp(127.0.0.1:3306)/skouter", + fmt.Sprintf("%s:%s@tcp(127.0.0.1:3306)/skouter", config["DBUser"], config["DBPass"])) + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + err = db.Ping() if err != nil { - // do something here like abort print("Bad database configuration: %v", err) panic(err) // maybe os.Exit(1) instead } - fmt.Print(getLoanType(db, 0, true)) + switch { + case match(p, "/api/loans", &args): + resp, err := getLoanType(db, 0, true) + + if resp != nil { + json.NewEncoder(w).Encode(resp) + } else { + json.NewEncoder(w).Encode(err) + } + + case match(p, "/api/fees", &args): + resp, err := getFees(db, 0) + + if resp != nil { + json.NewEncoder(w).Encode(resp) + } else { + json.NewEncoder(w).Encode(err) + } + } + +} + +func main() { + files := http.FileServer(http.Dir("")) http.Handle("/assets/", files) + http.HandleFunc("/api/", api) http.HandleFunc("/", route) log.Fatal(http.ListenAndServe(address, nil)) }