1
0
mirror of https://github.com/MADTeacher/go_basics.git synced 2025-11-23 21:34:47 +02:00
Files
go_basics/part_6/6.3/golang/todo_transaction/main.go
2025-06-16 11:31:09 +03:00

244 lines
5.7 KiB
Go

package main
import (
"errors"
"fmt"
"os"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
const dbName = "todo.db"
var ErrNotExists = errors.New("row not exists")
type Project struct {
ID int `gorm:"primary_key;autoIncrement:true;not null"`
Name string `gorm:"unique;not null"`
Description string
}
type ProjectTask struct {
ID int `gorm:"primary_key;autoIncrement;not null"`
Name string `gorm:"not null"`
Description string `gorm:"not null"`
Priority uint8 `gorm:"not null"`
IsDone bool `gorm:"not null"`
ProjectID int `gorm:"not null"`
Project *Project `gorm:"foreignKey:ProjectID;references:ID"`
}
func connectionToBD(pathToDB string) (db *gorm.DB, err error) {
if _, err := os.Stat(dbName); os.IsNotExist(err) {
db, err = gorm.Open(sqlite.Open(dbName), &gorm.Config{})
if err != nil {
return nil, err
}
fmt.Println("DB isn't exist")
db.AutoMigrate(&Project{}, &ProjectTask{})
putDefaultValuesToDB(db)
} else {
db, err = gorm.Open(sqlite.Open(dbName), &gorm.Config{})
if err != nil {
return nil, err
}
fmt.Println("DB already exists")
}
return
}
func putDefaultValuesToDB(db *gorm.DB) {
db.Transaction(func(tx *gorm.DB) error { // начало транзакции
firstProject := Project{
Name: "Go",
Description: "Roadmap for learning Go",
}
secondProject := Project{
Name: "One Year",
Description: "Tasks for the year",
}
tx.Create(&firstProject)
if err := tx.Create(&secondProject).Error; err != nil { //проверяем на наличие ошибок при записи
return err // вызываем отмену транзакции
}
tx.Create(&ProjectTask{
Name: "Variable",
Description: "Learning Go build-in variables",
Priority: 1,
Project: &firstProject,
})
if err := tx.Create(&ProjectTask{ //проверяем на наличие ошибок при записи
Name: "Struct",
Description: "Learning use struct in OOP code",
Priority: 3,
Project: &firstProject,
}).Error; err != nil {
return err // вызываем отмену транзакции
}
tx.Create(&ProjectTask{
Name: "Goroutine",
Description: "Learning concurrent programming",
Priority: 5,
Project: &firstProject,
})
tx.Create(&ProjectTask{
Name: "DataBase",
Description: "How write app with db",
Priority: 1,
Project: &firstProject,
})
tx.Create(&ProjectTask{
Name: "PhD",
Description: "Ph.D. in Technical Sciences",
Priority: 5,
Project: &secondProject,
})
tx.Create(&ProjectTask{
Name: "Losing weight",
Description: "Exercise and eat less chocolate",
Priority: 2,
Project: &secondProject,
})
tx.Create(&ProjectTask{
Name: "Пафос и превозмогание",
Description: "10к подписчиков на канале",
Priority: 2,
Project: &secondProject,
})
return nil
})
}
func GetAllProjects(db *gorm.DB) ([]Project, error) {
var projects []Project
tx := db.Find(&projects)
if tx.Error != nil {
return nil, tx.Error
}
if tx.RowsAffected == 0 {
return nil, ErrNotExists
}
return projects, nil
}
func GetAllTasks(db *gorm.DB) (tasks []ProjectTask, err error) {
tx := db.Find(&tasks)
if tx.Error != nil {
return nil, tx.Error
}
if tx.RowsAffected == 0 {
return nil, ErrNotExists
}
return
}
func printAllTasks(db *gorm.DB) {
tasks, err := GetAllTasks(db)
if err != nil {
return
}
fmt.Println("*********Tasks*********")
for _, it := range tasks {
fmt.Printf("TaskID: %v || Name: %v || Priority: %v || IsDone: %v || ProjID: %v\n",
it.ID, it.Name, it.Priority, it.IsDone, it.ProjectID)
}
}
func printAllProjects(db *gorm.DB) {
progects, err := GetAllProjects(db)
if err != nil {
return
}
fmt.Println("*********Projects*********")
for _, it := range progects {
fmt.Printf("ProjectID: %v || Name: %v || Desc: %v\n",
it.ID, it.Name, it.Description)
}
}
func printAllProjectAndTask(db *gorm.DB) {
printAllProjects(db)
printAllTasks(db)
}
func GetAllProjectTasks(db *gorm.DB, projectID int) (tasks []ProjectTask, err error) {
tx := db.Where("project_id", projectID).Find(&tasks)
if tx.Error != nil {
return nil, tx.Error
}
if tx.RowsAffected == 0 {
return nil, ErrNotExists
}
return
}
func printAllProjectTasks(db *gorm.DB, projectID int) {
tasks, err := GetAllProjectTasks(db, projectID)
if err != nil {
return
}
fmt.Println("*********Tasks*********")
for _, it := range tasks {
fmt.Printf("TaskID: %v || Name: %v || Priority: %v || IsDone: %v || ProjID: %v\n",
it.ID, it.Name, it.Priority, it.IsDone, it.ProjectID)
}
}
func main() {
db, _ := gorm.Open(sqlite.Open(dbName), &gorm.Config{DryRun: true})
var tasks []ProjectTask
stmt := db.Where("project_id", 1).Find(&tasks).Statement
fmt.Println(stmt.SQL.String())
stmt = db.Create(&ProjectTask{
Name: "Пафос и превозмогание",
Description: "10к подписчиков на канале",
Priority: 2,
ProjectID: 2,
}).Statement
fmt.Println(stmt.SQL.String())
firstProject := Project{
Name: "Go",
Description: "Roadmap for learning Go",
}
stmt = db.Create(&firstProject).Statement
fmt.Println(stmt.SQL.String())
}
func CreateProjects(db *gorm.DB) error {
tx := db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
if err := tx.Error; err != nil {
return err
}
if err := tx.Create(&Project{Name: "Oo"}).Error; err != nil {
tx.Rollback()
return err
}
if err := tx.Create(&Project{Name: "^_^"}).Error; err != nil {
tx.Rollback()
return err
}
return tx.Commit().Error
}