Parcourir la source

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.
master
Immanuel Onyeka il y a 2 ans
Parent
révision
ac5a9ec31a
3 fichiers modifiés avec 97 ajouts et 66 suppressions
  1. +15
    -14
      migrations/0_29092022_create_main_tables.sql
  2. +18
    -18
      migrations/seed.sql
  3. +64
    -34
      skouter.go

+ 15
- 14
migrations/0_29092022_create_main_tables.sql Voir le fichier

@@ -7,7 +7,7 @@ CREATE TABLE comparison (


CREATE TABLE branch ( CREATE TABLE branch (
id INT AUTO_INCREMENT, id INT AUTO_INCREMENT,
type ENUM('NMLS', 'FSRA'), type ENUM('NMLS', 'FSRA') NOT NULL,
num VARCHAR(40) NOT NULL, num VARCHAR(40) NOT NULL,
PRIMARY KEY (id) PRIMARY KEY (id)
); );
@@ -50,8 +50,8 @@ CREATE TABLE license (
* Types with branch_id and user_id values of null will be general cases. */ * Types with branch_id and user_id values of null will be general cases. */
CREATE TABLE loan_type ( CREATE TABLE loan_type (
id INT AUTO_INCREMENT, id INT AUTO_INCREMENT,
branch_id INT, branch_id INT NOT NULL,
user_id INT, user_id INT NOT NULL,
name VARCHAR(30) NOT NULL, name VARCHAR(30) NOT NULL,
FOREIGN KEY (branch_id) REFERENCES branch(id), FOREIGN KEY (branch_id) REFERENCES branch(id),
FOREIGN KEY (user_id) REFERENCES user(id), FOREIGN KEY (user_id) REFERENCES user(id),
@@ -60,9 +60,9 @@ CREATE TABLE loan_type (


CREATE TABLE borrower ( CREATE TABLE borrower (
id INT AUTO_INCREMENT, id INT AUTO_INCREMENT,
credit_score SMALLINT, credit_score SMALLINT NOT NULL,
monthly_income INT, monthly_income INT NOT NULL,
num TINYINT, /* Number of people borrowing. */ num TINYINT NOT NULL, /* Number of people borrowing. */
PRIMARY KEY (`id`) 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 /* 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 ( CREATE TABLE fee_template (
id INT AUTO_INCREMENT, id INT AUTO_INCREMENT,
user_id INT, user_id INT NOT NULL,
branch_id INT, branch_id INT NOT NULL,
amount INT, amount INT NOT NULL,
perc SMALLINT, /* Percentage of sale price instead of amount */ perc SMALLINT NOT NULL,
/* Percentage of sale price instead of amount */
type ENUM('Goverment', 'Title', 'Required', 'Lender', 'Other'), type ENUM('Goverment', 'Title', 'Required', 'Lender', 'Other'),
notes VARCHAR(255), notes VARCHAR(255) NOT NULL,
name VARCHAR(30), name VARCHAR(30) NOT NULL,
/* Group heading shown in report */ /* Group heading shown in report */
category VARCHAR(60), category VARCHAR(60) NOT NULL,
auto BOOLEAN NOT NULL, auto BOOLEAN NOT NULL,
/* If fee should be automatically applied */ /* If fee should be automatically applied */
PRIMARY KEY (`id`), PRIMARY KEY (`id`),


+ 18
- 18
migrations/seed.sql Voir le fichier

@@ -32,7 +32,7 @@ INSERT IGNORE INTO user (
'Giant', 'Giant',
'Coltrane', 'Coltrane',
sha2('test123', 256), sha2('test123', 256),
null, 0,
'USA', 'USA',
'Mortgage Broker', 'Mortgage Broker',
'unverified@example.com', 'unverified@example.com',
@@ -75,11 +75,11 @@ INSERT IGNORE INTO loan_type (
) VALUES ) VALUES
( (
(SELECT id FROM branch LIMIT 1), (SELECT id FROM branch LIMIT 1),
NULL, 0,
'testType' 'testType'
), ),
( (
NULL, 0,
(SELECT id FROM user WHERE email="manager@example.com" LIMIT 1), (SELECT id FROM user WHERE email="manager@example.com" LIMIT 1),
'manager idea' 'manager idea'
); );
@@ -94,7 +94,7 @@ INSERT IGNORE INTO fee_template (
name name
) VALUES ) VALUES
( (
NULL, 0,
(SELECT id FROM branch LIMIT 1), (SELECT id FROM branch LIMIT 1),
0, 0,
200, 200,
@@ -113,7 +113,7 @@ INSERT IGNORE INTO fee_template (
), ),
( (
(SELECT id FROM user WHERE email="test@example.com" LIMIT 1), (SELECT id FROM user WHERE email="test@example.com" LIMIT 1),
NULL, 0,
9900, 9900,
0, 0,
"Government", "Government",
@@ -122,7 +122,7 @@ INSERT IGNORE INTO fee_template (
), ),
( (
(SELECT id FROM user WHERE email="test@example.com" LIMIT 1), (SELECT id FROM user WHERE email="test@example.com" LIMIT 1),
NULL, 0,
0, 0,
400, 400,
'Lender', 'Lender',
@@ -136,27 +136,27 @@ INSERT IGNORE INTO loan_type (
name name
) VALUES ) VALUES
( (
NULL, 0,
NULL, 0,
"Conventional" "Conventional"
), ),
( (
NULL, 0,
NULL, 0,
"FHA" "FHA"
), ),
( (
NULL, 0,
NULL, 0,
"VA" "VA"
), ),
( (
NULL, 0,
NULL, 0,
"USDA" "USDA"
), ),
( (
NULL, 0,
(SELECT id FROM branch LIMIT 1), (SELECT id FROM branch LIMIT 1),
"Test" "Test"
); );
@@ -192,7 +192,7 @@ INSERT IGNORE INTO estimate (
( (
(SELECT id FROM user WHERE email="test@example.com" LIMIT 1), (SELECT id FROM user WHERE email="test@example.com" LIMIT 1),
(SELECT id FROM borrower ORDER BY id DESC LIMIT 1), (SELECT id FROM borrower ORDER BY id DESC LIMIT 1),
NULL, 0,
'Purchase', 'Purchase',
(SELECT id FROM loan_type WHERE name="Conventional"), (SELECT id FROM loan_type WHERE name="Conventional"),
3300000, 3300000,
@@ -209,7 +209,7 @@ INSERT IGNORE INTO estimate (
( (
(SELECT id FROM user WHERE email="manager@example.com" LIMIT 1), (SELECT id FROM user WHERE email="manager@example.com" LIMIT 1),
(SELECT id FROM borrower ORDER BY id DESC LIMIT 1), (SELECT id FROM borrower ORDER BY id DESC LIMIT 1),
NULL, 0,
'Purchase', 'Purchase',
(SELECT id FROM loan_type WHERE name="FHA"), (SELECT id FROM loan_type WHERE name="FHA"),
2510000, 2510000,
@@ -226,7 +226,7 @@ INSERT IGNORE INTO estimate (
( (
(SELECT id FROM user WHERE email="test@example.com" LIMIT 1), (SELECT id FROM user WHERE email="test@example.com" LIMIT 1),
(SELECT id FROM borrower ORDER BY id DESC LIMIT 1), (SELECT id FROM borrower ORDER BY id DESC LIMIT 1),
NULL, 0,
'Refinance', 'Refinance',
(SELECT id FROM loan_type WHERE name="USDA"), (SELECT id FROM loan_type WHERE name="USDA"),
8000000, 8000000,


+ 64
- 34
skouter.go Voir le fichier

@@ -9,6 +9,7 @@ import (
"database/sql" "database/sql"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"fmt" "fmt"
"encoding/json"
) )


type Page struct { type Page struct {
@@ -18,23 +19,23 @@ type Page struct {
} }


type LoanType struct { type LoanType struct {
id int Id int `json:"id"`
user sql.NullInt64 User int `json:"user"`
branch sql.NullInt64 Branch int `json:"branch"`
name string Name string `json:"name"`
} }


type FeeTemplate struct { type FeeTemplate struct {
id sql.NullInt64 Id int
user sql.NullInt64 User int
branch sql.NullInt64 Branch int
amount sql.NullInt64 Amount int
perc sql.NullInt64 Perc int
ftype sql.NullString Ftype string
notes sql.NullString Notes string
name sql.NullString Name string
category sql.NullString Category string
auto bool Auto bool
} }


type Estimate struct { type Estimate struct {
@@ -113,7 +114,7 @@ func getLoanType(db *sql.DB, id int, isUser bool) ([]LoanType, error) {
// Should be changed to specify user // Should be changed to specify user
rows, err := rows, err :=
db.Query("SELECT * FROM loan_type WHERE user_id = ? " + 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 { if err != nil {
return nil, fmt.Errorf("loan_type error: %v", err) 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 var loan LoanType


if err := rows.Scan( if err := rows.Scan(
&loan.user, &loan.Id,
&loan.branch, &loan.User,
&loan.name) &loan.Branch,
&loan.Name)
err != nil { err != nil {
log.Printf("Error occured fetching loan: %v", err) log.Printf("Error occured fetching loan: %v", err)
return nil, fmt.Errorf("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) loans = append(loans, loan)
} }


log.Printf("The loans: %v", loans)
return loans, nil return loans, nil
} }


@@ -155,16 +158,16 @@ func getFees(db *sql.DB, user int) ([]FeeTemplate, error) {
var fee FeeTemplate var fee FeeTemplate


if err := rows.Scan( if err := rows.Scan(
&fee.id, &fee.Id,
&fee.user, &fee.User,
&fee.branch, &fee.Branch,
&fee.amount, &fee.Amount,
&fee.perc, &fee.Perc,
&fee.ftype, &fee.Ftype,
&fee.notes, &fee.Notes,
&fee.name, &fee.Name,
&fee.category, &fee.Category,
&fee.auto) &fee.Auto)
err != nil { err != nil {
return nil, fmt.Errorf("The fees %q: %v", user, err) 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) { func route(w http.ResponseWriter, r *http.Request) {
var page Page var page Page
var args []string var args []string

p := r.URL.Path p := r.URL.Path

switch { switch {
case r.Method == "GET" && match(p, "/", &args): case r.Method == "GET" && match(p, "/", &args):
page = pages[ "home" ] page = pages[ "home" ]
@@ -198,24 +201,51 @@ func route(w http.ResponseWriter, r *http.Request) {
page.Render(w) page.Render(w)
} }


func main() { func api(w http.ResponseWriter, r *http.Request) {
files := http.FileServer(http.Dir("")) var args []string
// var response string
p := r.URL.Path
db, err := sql.Open("mysql", 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["DBUser"],
config["DBPass"])) config["DBPass"]))


w.Header().Set("Content-Type", "application/json; charset=UTF-8")

err = db.Ping() err = db.Ping()
if err != nil { if err != nil {
// do something here like abort
print("Bad database configuration: %v", err) print("Bad database configuration: %v", err)
panic(err) panic(err)
// maybe os.Exit(1) instead // 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.Handle("/assets/", files)
http.HandleFunc("/api/", api)
http.HandleFunc("/", route) http.HandleFunc("/", route)
log.Fatal(http.ListenAndServe(address, nil)) log.Fatal(http.ListenAndServe(address, nil))
} }

||||||
x
 
000:0
Chargement…
Annuler
Enregistrer