Created
August 26, 2021 15:23
-
-
Save alochym01/8170f5b101dec6b51c05a6073004a5db to your computer and use it in GitHub Desktop.
Create a simple Pagination - golang programming
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"database/sql" | |
"encoding/json" | |
"flag" | |
"fmt" | |
"log" | |
"net/http" | |
"os" | |
"strconv" | |
"github.com/bmizerany/pat" | |
_ "github.com/mattn/go-sqlite3" | |
) | |
// DB connection | |
var DB *sql.DB | |
func main() { | |
var err error | |
// Define a new command-line flag with the name 'addr', a default value of ":4000" | |
// and some short help text explaining what the flag controls. The value of the | |
// flag will be stored in the addr variable at runtime. | |
addr := flag.String("addr", ":8080", "HTTP network address") | |
// Use log.New() to create a logger for writing information messages. This takes | |
// three parameters: the destination to write the logs to (os.Stdout), a string | |
// prefix for message (INFO followed by a tab), and flags to indicate what | |
// additional information to include (local date and time). Note that the flags | |
// are joined using the bitwise OR operator |. | |
// InfoLog = log.New(os.Stdout, "INFO\t", log.Ldate|log.Ltime|log.Lshortfile) | |
infoLog := log.New(os.Stdout, "INFO\t", log.Ldate|log.Ltime|log.Llongfile) | |
// Create a logger for writing error messages in the same way, but use stderr as | |
// the destination and use the log.Lshortfile flag to include the relevant | |
// file name and line number. | |
errLog := log.New(os.Stderr, "ERROR\t", log.Ldate|log.Ltime|log.Llongfile) | |
mux := pat.New() | |
// userHandler | |
// mux.Get("/user", http.HandlerFunc(user.Get)) | |
mux.Get("/user/create", http.HandlerFunc(CreateUser)) | |
mux.Get("/user", http.HandlerFunc(GetUser)) | |
// Importantly, we use the flag.Parse() function to parse the command-line flag. | |
// This reads in the command-line flag value and assigns it to the addr | |
// variable. You need to call this *before* you use the addr variable | |
// otherwise it will always contain the default value of ":4000". If any errors are | |
// encountered during parsing the application will be terminated. | |
flag.Parse() | |
// sqlite | |
DB, err = sql.Open("sqlite3", "alochym.db") | |
if err != nil { | |
panic(err) | |
} | |
defer DB.Close() | |
infoLog.Println("starting server on", *addr) | |
err = http.ListenAndServe(*addr, mux) | |
errLog.Fatal(err) | |
} | |
// User models | |
type User struct { | |
ID int | |
Name string | |
Email string | |
Password string | |
} | |
// Pagination Object | |
type Pagination struct { | |
Next int | |
Previous int | |
RecordPerPage int | |
CurrentPage int | |
TotalPage int | |
} | |
// Get all User accounts | |
func (u User) Get(page int) (interface{}, error) { | |
var ( | |
// Create empty Album | |
record = User{} | |
// Create empty slice Album | |
users = []User{} | |
data = map[string]interface{}{} | |
) | |
limit := 10 | |
offset := limit * (page - 1) | |
data["Page"] = *pagination("users", limit, page) | |
// sqlstmt - Avoid SQL Injection Attack | |
// Using limit and offset to get records | |
sqlstmt := fmt.Sprintf("SELECT id, name, email FROM users order by id desc limit %d offset %d", limit, offset) | |
fmt.Println(sqlstmt) | |
rows, _ := DB.Query(sqlstmt) | |
// close rows query | |
defer rows.Close() | |
for rows.Next() { | |
err := rows.Scan(&record.ID, &record.Name, &record.Email) | |
if err != nil { | |
// check server err | |
return nil, err | |
} | |
// append record to albums slice | |
users = append(users, record) | |
} | |
data["Records"] = users | |
return data, nil | |
} | |
// GetUser return all user records | |
func GetUser(w http.ResponseWriter, r *http.Request) { | |
u := User{} | |
page, _ := strconv.Atoi(r.URL.Query().Get("page")) | |
if page == 0 { | |
page = 1 | |
} | |
result, _ := u.Get(page) | |
w.Header().Set("Content-Type", "application/json") | |
// Transform to JSON response | |
json.NewEncoder(w).Encode(result) | |
} | |
// CreateUser mock data | |
func CreateUser(w http.ResponseWriter, r *http.Request) { | |
sqldroptable := fmt.Sprint("DROP TABLE users;") | |
DB.Exec(sqldroptable) | |
sqltable := fmt.Sprintf("CREATE TABLE users (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL, password CHAR(60) NOT NULL, created datetime default current_timestamp)") | |
// Execute SQL Statements | |
_, err := DB.Exec(sqltable) | |
if err != nil { | |
fmt.Println(err.Error()) | |
} | |
fmt.Println("User table created") | |
var users = []User{ | |
{Name: "Alice Jones", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Nguyen Ha", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Ngo Thi To Nhu", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Hiep", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Kim Hoa", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Alice Jones", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Nguyen Ha", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Ngo Thi To Nhu", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Hiep", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Kim Hoa", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Alice Jones", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Nguyen Ha", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Ngo Thi To Nhu", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Hiep", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Kim Hoa", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Alice Jones", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Nguyen Ha", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Ngo Thi To Nhu", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Hiep", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Kim Hoa", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Alice Jones", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Nguyen Ha", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Ngo Thi To Nhu", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Hiep", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Kim Hoa", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Alice Jones", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Nguyen Ha", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Ngo Thi To Nhu", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Hiep", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Kim Hoa", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Alice Jones", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Nguyen Ha", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Ngo Thi To Nhu", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Hiep", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Kim Hoa", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Alice Jones", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Nguyen Ha", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Ngo Thi To Nhu", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Hiep", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Kim Hoa", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Alice Jones", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Nguyen Ha", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Ngo Thi To Nhu", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Hiep", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Kim Hoa", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Alice Jones", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Nguyen Ha", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Ngo Thi To Nhu", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Hiep", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Kim Hoa", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Alice Jones", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Nguyen Ha", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Ngo Thi To Nhu", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Hiep", Email: "[email protected]", Password: "alochym@123"}, | |
{Name: "Do Thi Kim Hoa", Email: "[email protected]", Password: "alochym@123"}, | |
} | |
for _, v := range users { | |
sqlstmt := fmt.Sprintf("INSERT INTO users(name, email, password) VALUES(\"%s\", \"%s\", \"%s\")", | |
v.Name, | |
v.Email, | |
v.Password, | |
) | |
DB.Exec(sqlstmt) | |
} | |
w.Write([]byte("Get All Snippet")) | |
} | |
// sqlHelper | |
// running sql command and return error | |
func sqlHelper(db *sql.DB, sqlstmt string) error { | |
// Execute SQL Statements | |
fmt.Println(sqlstmt) | |
result, err := db.Exec(sqlstmt) | |
// err check for DB operation | |
if err != nil { | |
return err | |
} | |
rowCount, err := result.RowsAffected() | |
// error check for RowsAffected function | |
if err != nil { | |
return err | |
} | |
// there is no row found | |
if rowCount == 0 { | |
return sql.ErrNoRows | |
} | |
return nil | |
} | |
// Generated Pagination Meta data | |
func pagination(table string, limit, page int) *Pagination { | |
var ( | |
tmpl = Pagination{} | |
recordcount int | |
) | |
// Count all record | |
sqltable := fmt.Sprintf("SELECT count(id) FROM %s", table) | |
DB.QueryRow(sqltable).Scan(&recordcount) | |
total := (recordcount / limit) | |
// Calculator Total Page | |
remainder := (recordcount % limit) | |
if remainder == 0 { | |
tmpl.TotalPage = total | |
} else { | |
tmpl.TotalPage = total + 1 | |
} | |
// Set current/record per page meta data | |
tmpl.CurrentPage = page | |
tmpl.RecordPerPage = limit | |
// Calculator the Next/Previous Page | |
if page <= 0 { | |
tmpl.Next = page + 1 | |
} else if page < tmpl.TotalPage { | |
tmpl.Previous = page - 1 | |
tmpl.Next = page + 1 | |
} else if page == tmpl.TotalPage { | |
tmpl.Previous = page - 1 | |
tmpl.Next = 0 | |
} | |
return &tmpl | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
you are running
count
query every time. It is not performance optimized.