百木园-与人分享,
就是让自己快乐。

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 读写文件

功能演示

  1. 列出全部图书
$ .\\bookstore.exe get -all
Id      Title                   Author
1       Go语言圣经              Ailen A
2       Java编程思想            Bruce Eckel
3       流畅的Python            Luciano Ramalho
4       PHP权威指南             CENJW
  1. 通过id获取相应图书
$ .\\bookstore.exe get -id 1
Id      Title           Author
1       Go语言圣经      Ailen A
  1. 添加图书
$ .\\bookstore.exe add -id 123 -title \'Head First Go\' -author unknown
add successfully!
  1. 添加图书,如果已经存在相同id的图书,提示已存在
$ .\\bookstore.exe add -id 1 -title test -author test 
2022/06/24 18:05:44 Book already exists.
  1. 更新图书
$ .\\bookstore.exe update -id 123 -title \'head first go\' -author UNKNOWN
update successfully!
  1. 删除图书
$ .\\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[1] {
	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\"`
	Title  string `json:\"title\"`
	Author string `json:\"author\"`
}

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

	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[2:])

	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[i] = 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[1])
}

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

	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[i+1:]...)
				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)
	}
}

本文来自博客园,作者:Arway,转载请注明原文链接:https://www.cnblogs.com/cenjw/p/gobeginner-proj-bookstore-cli.html


来源:https://www.cnblogs.com/cenjw/p/gobeginner-proj-bookstore-cli.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » go入门项目:(1) 基于命令行的图书的增删查改

相关推荐

  • 暂无文章