Преглед изворни кода

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 пре 2 година
родитељ
комит
ac5a9ec31a
3 измењених фајлова са 97 додато и 66 уклоњено
  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 Прегледај датотеку

@@ -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`),


+ 18
- 18
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,


+ 64
- 34
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))
}

Loading…
Откажи
Сачувај