Go Lang Crash Course

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 error Type:
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

  1. Installing and Importing Dependencies:
package main

import (
    "database/sql"
    "fmt"

    _ "github.com/go-sql-driver/mysql"
)
  1. 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!")
}
  1. 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!")
}
  1. 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)
}
  1. 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

  1. 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")
}
  1. 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")
}
  1. 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")
}
  1. 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")
}
  1. 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.