种地 发表于 2022-8-9 14:45:04

go入门项目:(1) 基于命令行的图书的增删查改

Go 语言入门练手项目系列

[*]01 基于命令行的图书的增删查改
[*]02 文件管理
持续更新中...
> 本文来自博客园,作者:Arway,转载请注明原文链接:https://www.cnblogs.com/cenjw/p/gobeginner-proj-bookstore-cli.html介绍

这是一个基于go应用程序命令行的bookstore小项目,具体实现了图书的增删改查,适合刚入门go的朋友熟悉go的语法。
知识点


[*]go flag,提供了命令行参数解析的功能
[*]go json的序列化与反序列化
[*]go ioutil 读写文件
功能演示


[*]列出全部图书
$ .\bookstore.exe get -all
Id      Title                   Author
1       Go语言圣经            Ailen A
2       Java编程思想            Bruce Eckel
3       流畅的Python            Luciano Ramalho
4       PHP权威指南             CENJW
[*]通过id获取相应图书
$ .\bookstore.exe get -id 1
Id      Title         Author
1       Go语言圣经      Ailen A
[*]添加图书
$ .\bookstore.exe add -id 123 -title 'Head First Go' -author unknown
add successfully!
[*]添加图书,如果已经存在相同id的图书,提示已存在
$ .\bookstore.exe add -id 1 -title test -author test
2022/06/24 18:05:44 Book already exists.
[*]更新图书
$ .\bookstore.exe update -id 123 -title 'head first go' -author UNKNOWN
update successfully!
[*]删除图书
$ .\bookstore.exe delete -id 123
Delete successfully!本文来自博客园,作者:Arway,转载请注明原文链接:https://www.cnblogs.com/cenjw/p/gobeginner-proj-bookstore-cli.html
功能实现

main.go
func main() {
        // get book/books
        getCmd := flag.NewFlagSet("get", flag.ExitOnError)
        getAll := getCmd.Bool("all", false, "List all books")
        getId := getCmd.String("id", "", "Get a book by id")

        // add/update book
        addCmd := flag.NewFlagSet("add", flag.ExitOnError)
        addId := addCmd.String("id", "", "Book id")
        addTitle := addCmd.String("title", "", "Book title")
        addAuthor := addCmd.String("author", "", "Book author")

        // delete book
        deleteCmd := flag.NewFlagSet("delete", flag.ExitOnError)
        deleteId := deleteCmd.String("id", "", "Book id")
       
        // check command
        if len(os.Args) < 2 {
                log.Fatal("Expected get, add, update, delete commands.")
        }

        switch os.Args {
        case "get":
                handleGetBooks(getCmd, getAll, getId)
        case "add":
                handleAddOrUpdateBook(addCmd, addId, addTitle, addAuthor, true)
        case "update":
                handleAddOrUpdateBook(addCmd, addId, addTitle, addAuthor, false)
        case "delete":
                handleDeleteBook(deleteCmd, deleteId)
        default:
                fmt.Println("Pls provide get, add, update, delete commands.")
        }

}books.go
type Book struct {
        Id   string `json:"id"`
        Titlestring `json:"title"`
        Author string `json:"author"`
}

// get all the books logic
func handleGetBooks(getCmd *flag.FlagSet, all *bool, id *string) {
        getCmd.Parse(os.Args)

        if !*all && *id == "" {
                fmt.Println("subcommand --all or --id needed") // PrintDefault打印集合中所有注册好的flag的默认值。除非另外配置,默认输出到标准错误输出中。
                getCmd.PrintDefaults()
                os.Exit(1)
        }

        if *all {
                books := getBooks()
                fmt.Println("Id\tTitle\t\t\tAuthor\t")
                for _, book := range books {
                        fmt.Printf("%v\t%v\t\t%v\t\n", book.Id, book.Title, book.Author)
                }
        }

        if *id != "" {
                var isExist bool
                books := getBooks()
                fmt.Println("Id\tTitle\t\tAuthor\t")
                for _, book := range books {
                        if book.Id == *id {
                                fmt.Printf("%v\t%v\t%v\t\n", book.Id, book.Title, book.Author)
                                isExist = true
                        }
                }

                if !isExist {
                        log.Fatal("Book not found!")
                }
        }
}

// add or update a book logic
// addBook: true denote add a new book to file, false denote update a book
func handleAddOrUpdateBook(addCmd *flag.FlagSet, id, title, author *string, addBook bool) {
        addCmd.Parse(os.Args)

        if *id == "" || *title == "" || *author == "" {
                addCmd.PrintDefaults()
                log.Fatal("Pls provide id, title, author commands.")
        }
        books := getBooks()
        var newBook Book
        if addBook {
                for _, book := range books {
                        if book.Id == *id {
                                log.Fatal("Book already exists.")       
                        } else {
                                newBook = Book{*id, *title, *author}
                                books = append(books, newBook)
                                break
                        }
                }
               
        } else {
                var isExist bool
                for i, book := range books {
                        if book.Id == *id {
                                books = Book{Id: *id, Title: *title, Author: *author}
                                isExist = true
                        }
                }

                err := saveBooks(books)
                checkError(err)

                if !isExist {
                        log.Fatal("Book not found")
                }

        }

        saveBooks(books)

        fmt.Printf("%s successfully!\n", os.Args)
}

func handleDeleteBook(deleteCmd *flag.FlagSet, id *string) {
        deleteCmd.Parse(os.Args)

        if *id == "" {
                deleteCmd.PrintDefaults()
                log.Fatal("Pls provide id command.")
        }

        if *id != "" {
                var isExist bool
                books := getBooks()
                for i, book := range books {
                        if book.Id == *id {
                                books = append(books[:i], books...)
                                isExist = true
                        }
                }

                if !isExist {
                        log.Fatal("Book not found!")
                }

                err := saveBooks(books)
                checkError(err)

                fmt.Println("Delete successfully!")
        }
}

func saveBooks(books []Book) error {
        bookBytes, err := json.Marshal(books)
        checkError(err)
        err = ioutil.WriteFile("./books.json", bookBytes, 0644)
        return err
}

func getBooks() (books []Book) {
        bookBytes, err := ioutil.ReadFile("./books.json")
        checkError(err)
        err = json.Unmarshal(bookBytes, &books)
        checkError(err)
        return books
}

func checkError(err error) {
        if err != nil {
                log.Fatal("Error happended ", err)
        }
}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: go入门项目:(1) 基于命令行的图书的增删查改