Basics of Go
- Variables and Constants:
 
package main
import "fmt"
func main() {
    var message string = "Hello, Go!"
    fmt.Println(message)
    const pi = 3.14159
    fmt.Println(pi)
}
- Data Types and Type Conversion:
 
package main
import "fmt"
func main() {
    var age int = 25
    fmt.Println(age)
    var price float64 = 9.99
    fmt.Println(price)
    var isTrue bool = true
    fmt.Println(isTrue)
    var name string = "John"
    fmt.Println(name)
    // Type conversion
    var num int = 42
    var result float64 = float64(num)
    fmt.Println(result)
}
Operators
package main
import "fmt"
func main() {
    var a = 10
    var b = 5
    fmt.Println(a + b)
    fmt.Println(a - b)
    fmt.Println(a * b)
    fmt.Println(a / b)
    fmt.Println(a % b)
    var isTrue = true
    fmt.Println(!isTrue)
}
Control Structures: if-else and switch:
package main
import "fmt"
func main() {
    var num = 5
    if num > 0 {
        fmt.Println("Number is positive")
    } else if num < 0 {
        fmt.Println("Number is negative")
    } else {
        fmt.Println("Number is zero")
    }
    var day = "Monday"
    switch day {
    case "Monday":
        fmt.Println("It's Monday")
    case "Tuesday":
        fmt.Println("It's Tuesday")
    default:
        fmt.Println("It's another day")
    }
}
Loops: for and range
package main
import "fmt"
func main() {
    // For loop
    for i := 1; i <= 5; i++ {
        fmt.Println(i)
    }
    // Range loop
    nums := []int{1, 2, 3, 4, 5}
    for index, value := range nums {
        fmt.Println(index, value)
    }
}
Functions in Go
- Simple Function:
 
package main
import "fmt"
func add(a, b int) int {
    return a + b
}
func main() {
    result := add(3, 5)
    fmt.Println(result)
}
- Function with Multiple Return Values:
 
package main
import "fmt"
func divide(a, b int) (int, int) {
    quotient := a / b
    remainder := a % b
    return quotient, remainder
}
func main() {
    q, r := divide(10, 3)
    fmt.Println("Quotient:", q)
    fmt.Println("Remainder:", r)
}
- Variadic Function:
 
package main
import "fmt"
func sum(numbers ...int) int {
    total := 0
    for _, num := range numbers {
        total += num
    }
    return total
}
func main() {
    result := sum(1, 2, 3, 4, 5)
    fmt.Println(result)
}
- Anonymous Functions and Closures:
 
package main
import "fmt"
func main() {
    add := func(a, b int) int {
        return a + b
 }
    result := add(3, 5)
    fmt.Println(result)
}
- Recursion:
 
package main
import "fmt"
func factorial(n int) int {
    if n == 0 {
        return 1
    }
    return n * factorial(n-1)
}
func main() {
    result := factorial(5)
    fmt.Println(result)
}
Arrays, Slices, and Maps in Go
- Arrays:
 
package main
import "fmt"
func main() {
    var numbers [5]int
    numbers[0] = 1
    numbers[1] = 2
    numbers[2] = 3
    numbers[3] = 4
    numbers[4] = 5
    fmt.Println(numbers)
    var matrix [3][3]int
    matrix[0] = [3]int{1, 2, 3}
    matrix[1] = [3]int{4, 5, 6}
    matrix[2] = [3]int{7, 8, 9}
    fmt.Println(matrix)
}
- Slices:
 
package main
import "fmt"
func main() {
    numbers := []int{1, 2, 3, 4, 5}
    fmt.Println(numbers)
    fmt.Println(numbers[1:4]) // Slicing a slice
    numbers = append(numbers, 6) // Appending an element
    fmt.Println(numbers)
    numbers = append(numbers[:2], numbers[3:]...) // Removing an element
    fmt.Println(numbers)
}
- Maps:
 
package main
import "fmt"
func main() {
    person := map[string]string{
        "name":  "John",
        "age":   "30",
        "email": "john@example.com",
    }
    fmt.Println(person)
    fmt.Println(person["name"])
    person["city"] = "New York" // Adding a new key-value pair
    fmt.Println(person)
    delete(person, "age") // Removing a key-value pair
    fmt.Println(person)
}
- Iterating over Slices and Maps:
 
package main
import "fmt"
func main() {
    numbers := []int{1, 2, 3, 4, 5}
    for index, value := range numbers {
        fmt.Println(index, value)
    }
    person := map[string]string{
        "name":  "John",
        "age":   "30",
        "email": "john@example.com",
    }
    for key, value := range person {
        fmt.Println(key, ":", value)
    }
}
Structs and Methods in Go
- Structs:
 
package main
import "fmt"
type Person struct {
    name    string
    age     int
    address string
}
func main() {
    person := Person{"John", 30, "New York"}
    fmt.Println(person)
    fmt.Println(person.name)
    fmt.Println(person.age)
    fmt.Println(person.address)
}
- Methods:
 
package main
import "fmt"
type Rectangle struct {
    width  float64
    height float64
}
func (r Rectangle) area() float64 {
    return r.width * r.height
}
func main() {
    rect := Rectangle{3.0, 4.0}
    fmt.Println(rect.area())
}
Packages and Error Handling in Go
- Packages:
 
package main
import (
    "fmt"
    "math"
)
func main() {
    fmt.Println(math
.Sqrt(16))
}
- Error Handling with 
errorType: 
package main
import (
    "fmt"
    "math"
)
func calculateSqrt(num float64) (float64, error) {
    if num < 0 {
        return 0, fmt.Errorf("Cannot calculate square root of a negative number")
    }
    return math.Sqrt(num), nil
}
func main() {
    result, err := calculateSqrt(-9)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(result)
    }
}
- Custom Error Types:
 
package main
import (
    "fmt"
    "math"
)
type NegativeNumberError struct {
    number float64
}
func (e NegativeNumberError) Error() string {
    return fmt.Sprintf("Cannot calculate square root of a negative number: %f", e.number)
}
func calculateSqrt(num float64) (float64, error) {
    if num < 0 {
        return 0, NegativeNumberError{num}
    }
    return math.Sqrt(num), nil
}
func main() {
    result, err := calculateSqrt(-9)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(result)
    }
}
Database Connection
- Installing and Importing Dependencies:
 
package main
import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
)
- Establishing a Database Connection:
 
func main() {
    // Database connection parameters
    db, err := sql.Open("mysql", "username:password@tcp(localhost:3306)/database_name")
    if err != nil {
        panic(err)
    }
    defer db.Close()
    // Check if the connection is successful
    err = db.Ping()
    if err != nil {
        panic(err)
    }
    fmt.Println("Connected to the database!")
}
- Creating the “users” Table:
 
func main() {
    db, err := sql.Open("mysql", "username:password@tcp(localhost:3306)/database_name")
    if err != nil {
        panic(err)
    }
    defer db.Close()
    createTableQuery := `
        CREATE TABLE IF NOT EXISTS users (
            id INT AUTO_INCREMENT PRIMARY KEY,
            name VARCHAR(50) NOT NULL,
            age INT,
            city VARCHAR(50),
            salary FLOAT,
            added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
        );
    `
    _, err = db.Exec(createTableQuery)
    if err != nil {
        panic(err)
    }
    fmt.Println("Table 'users' created successfully!")
}
- Inserting Data into the “users” Table:
 
func main() {
    db, err := sql.Open("mysql", "username:password@tcp(localhost:3306)/database_name")
    if err != nil {
        panic(err)
    }
    defer db.Close()
    insertQuery := `
        INSERT INTO users (name, age, city, salary)
        VALUES (?, ?, ?, ?);
    `
    result, err := db.Exec(insertQuery, "John Doe", 30, "New York", 5000.0)
    if err != nil {
        panic(err)
    }
    lastInsertID, err := result.LastInsertId()
    if err != nil {
        panic(err)
    }
    fmt.Println("Inserted record ID:", lastInsertID)
}
- Querying Data from the “users” Table:
 
func main() {
    db, err := sql.Open("mysql", "username:password@tcp(localhost:3306)/database_name")
    if err != nil {
        panic(err)
    }
    defer db.Close()
    selectQuery := `
        SELECT id, name, age, city, salary, added_at, updated_at
        FROM users;
    `
    rows, err := db.Query(selectQuery)
    if err != nil {
        panic(err)
    }
    defer rows.Close()
    for rows.Next() {
        var id int
        var name string
        var age int
        var city string
        var salary float64
        var addedAt string
        var updatedAt string
        err := rows.Scan(&id, &name, &age, &city, &salary, &addedAt, &updatedAt)
        if err != nil {
            panic(err)
        }
        fmt.Println("ID:", id)
        fmt.Println("Name:", name)
        fmt.Println("Age:", age)
        fmt.Println("City:", city)
        fmt.Println("Salary:", salary)
        fmt.Println("Added At:", addedAt)
        fmt
.Println("Updated At:", updatedAt)
        fmt.Println()
    }
}
Go and Gin Framework
- Retrieving All Users:
 
func main() {
    router := gin.Default()
    // ...
    router.GET("/users", func(c *gin.Context) {
        selectQuery := `
            SELECT id, name, age, city, salary, added_at, updated_at
            FROM users;
        `
        rows, err := db.Query(selectQuery)
        if err != nil {
            c.JSON(500, gin.H{"error": err.Error()})
            return
        }
        defer rows.Close()
        users := []gin.H{}
        for rows.Next() {
            var id int
            var name string
            var age int
            var city string
            var salary float64
            var addedAt string
            var updatedAt string
            err := rows.Scan(&id, &name, &age, &city, &salary, &addedAt, &updatedAt)
            if err != nil {
                c.JSON(500, gin.H{"error": err.Error()})
                return
            }
            user := gin.H{
                "id":        id,
                "name":      name,
                "age":       age,
                "city":      city,
                "salary":    salary,
                "added_at":  addedAt,
                "updated_at": updatedAt,
            }
            users = append(users, user)
        }
        c.JSON(200, users)
    })
    // ...
    router.Run(":8080")
}
- Deleting a User:
 
func main() {
    router := gin.Default()
    // ...
    router.DELETE("/users/:id", func(c *gin.Context) {
        id := c.Param("id")
        deleteQuery := `
            DELETE FROM users
            WHERE id = ?;
        `
        result, err := db.Exec(deleteQuery, id)
        if err != nil {
            c.JSON(500, gin.H{"error": err.Error()})
            return
        }
        rowsAffected, err := result.RowsAffected()
        if err != nil {
            c.JSON(500, gin.H{"error": err.Error()})
            return
        }
        if rowsAffected == 0 {
            c.JSON(404, gin.H{"message": fmt.Sprintf("User with ID %s not found", id)})
        } else {
            c.JSON(200, gin.H{"message": fmt.Sprintf("User with ID %s deleted", id)})
        }
    })
    // ...
    router.Run(":8080")
}
- Adding a New User:
 
func main() {
    router := gin.Default()
    // ...
    router.POST("/users", func(c *gin.Context) {
        var user struct {
            Name   string  `json:"name"`
            Age    int     `json:"age"`
            City   string  `json:"city"`
            Salary float64 `json:"salary"`
        }
        if err := c.ShouldBindJSON(&user); err != nil {
            c.JSON(400, gin.H{"error": err.Error()})
            return
        }
        insertQuery := `
            INSERT INTO users (name, age, city, salary)
            VALUES (?, ?, ?, ?);
        `
        result, err := db.Exec(insertQuery, user.Name, user.Age, user.City, user.Salary)
        if err != nil {
            c.JSON(500, gin.H{"error": err.Error()})
            return
        }
        lastInsertID, err := result.LastInsertId()
        if err != nil {
            c
.JSON(500, gin.H{"error": err.Error()})
            return
        }
        c.JSON(201, gin.H{"message": fmt.Sprintf("User created with ID %d", lastInsertID)})
    })
    // ...
    router.Run(":8080")
}
- Fetching a Single User:
 
func main() {
    router := gin.Default()
    // ...
    router.GET("/users/:id", func(c *gin.Context) {
        id := c.Param("id")
        selectQuery := `
            SELECT id, name, age, city, salary, added_at, updated_at
            FROM users
            WHERE id = ?;
        `
        row := db.QueryRow(selectQuery, id)
        var user struct {
            ID        int     `json:"id"`
            Name      string  `json:"name"`
            Age       int     `json:"age"`
            City      string  `json:"city"`
            Salary    float64 `json:"salary"`
            AddedAt   string  `json:"added_at"`
            UpdatedAt string  `json:"updated_at"`
        }
        err := row.Scan(&user.ID, &user.Name, &user.Age, &user.City, &user.Salary, &user.AddedAt, &user.UpdatedAt)
        if err != nil {
            c.JSON(500, gin.H{"error": err.Error()})
            return
        }
        c.JSON(200, user)
    })
    // ...
    router.Run(":8080")
}
- Updating an Existing User:
 
func main() {
    router := gin.Default()
    // ...
    router.PUT("/users/:id", func(c *gin.Context) {
        id := c.Param("id")
        var user struct {
            Name   string  `json:"name"`
            Age    int     `json:"age"`
            City   string  `json:"city"`
            Salary float64 `json:"salary"`
        }
        if err := c.ShouldBindJSON(&user); err != nil {
            c.JSON(400, gin.H{"error": err.Error()})
            return
        }
        updateQuery := `
            UPDATE users
            SET name = ?, age = ?, city = ?, salary = ?
            WHERE id = ?;
        `
        result, err := db.Exec(updateQuery, user.Name, user.Age, user.City, user.Salary, id)
        if err != nil {
            c.JSON(500, gin.H{"error": err.Error()})
            return
        }
        rowsAffected, err := result.RowsAffected()
        if err != nil {
            c.JSON(500, gin.H{"error": err.Error()})
            return
        }
        if rowsAffected == 0 {
            c.JSON(404, gin.H{"message": fmt.Sprintf("User with ID %s not found", id)})
        } else {
            c.JSON(200, gin.H{"message": fmt.Sprintf("User with ID %s updated", id)})
        }
    })
    // ...
    router.Run(":8080")
}
Please make sure to replace "username", "password", and "database_name" with your actual MySQL database credentials and database name.