حساب‌فان (دیتابیس و متعلقات)

حالا قصد داریم دیتابیس به پروژه اضافه کنیم، برای این کار به ORM و migration و seed نیاز داریم.همونطور که تو پست مربوط به بک‌اند توضیح دادم از upper-db استفاده می‌کنم، چون خیلی سادس، داکیومنت خوبی داره، برای اکثر دیتابیس‌های ریلیشن، آداپتر داره و...برای مایگریشن و سید از rubenv/sql-migrate استفاده میکنم چون فوق العاده سادس، استاندارده، چیز اضافه نداره و قابل اعتماده.پس برای اضافه کردن پکیج دیتابیس فایل glide.yaml به این صورت تغییر میدیم:package: gitlab.com/erfun/hesabFun homepage: https://hesabfun.com owners: - name: ErFUN KH email: erfun.kh@gmail.com homepage: https://erfun.net import: - package: github.com/gin-gonic/gin # testing package - package: github.com/stretchr/testify # ORM - package: github.com/go-sql-driver/mysql - package: upper.io/db.v3/mysqlو فایل main.go به این صورت تغییر میدیم:package main import ( "upper.io/db.v3/mysql" "upper.io/db.v3/lib/sqlbuilder" "os" "log" ) var settings = mysql.ConnectionURL{ Database: "YOUR_MYSQL_DATABASE", Host: "YOUR_MYSQL_ADDRESS", User: "YOUR_MYSQL_USERNAME", Password: "YOUR_MYSQL_PASSWORD", } var MySql sqlbuilder.Database func main() { var DBError error MySql, DBError = mysql.Open(settings) if DBError != nil { log.Fatal("MySQL Error: ", DBError) } MySql.SetLogging(false) defer MySql.Close() router := setupRouter() router.Run() // listen and serve on 0.0.0.0:8080 }خیلی خوب، الآن اپلیکیشن به دیتابیس MySQL وصل میشه، ولی همونطور که می‌بینید تمام اطلاعات دیتابیس از جمله یوزر و پسورد تو کد نوشته شده، قرار نیست همینطور بمونه چون اگر تیم داشته باشید ممکنه یوزر و پسورد دیتابیس هرکسی رو سیستم شخصیش فرق داشته باشه، همچنین دلیلی نداره یوزر و پسورد دیتابیس اصلی به همه دولوپرها بدید، از همه مهمتر برای تست به مشکل می‌خوریم چون قراره دیتابیس حسابی کثیف کنیم.منم مثل همه از متغییرهای سیستم استفاده میکنم، با استفاده از پکیج goDotEnv یه فایل .env میسازیم و هردفعه اطلاعاتش میخونیم و رو سیستم ست میکنیم.بنابراین پکیج به پکیج‌منیجر اضافه میکنیم:package: gitlab.com/erfun/hesabFun homepage: https://hesabfun.com owners: - name: ErFUN KH email: erfun.kh@gmail.com homepage: https://erfun.net import: - package: github.com/gin-gonic/gin # testing package - package: github.com/stretchr/testify # ORM - package: github.com/go-sql-driver/mysql - package: upper.io/db.v3/mysql # Load environment variables from `.env` - package: github.com/joho/godotenvهمچنین جهت لود متغییرها پکیج goDotEnv لود میکنیم و تنظیمات دیتابیس کمی تغییر میدیم:package main import ( "os" "log" "upper.io/db.v3/mysql" "upper.io/db.v3/lib/sqlbuilder" _ "github.com/joho/godotenv/autoload" ) var settings = mysql.ConnectionURL{ Database: os.Getenv("MYSQL_DATABASE"), Host: os.Getenv("MYSQL_ADDRESS"), User: os.Getenv("MYSQL_USERNAME"), Password: os.Getenv("MYSQL_PASSWORD"), } var MySql sqlbuilder.Database func main() { var DBError error MySql, DBError = mysql.Open(settings) if DBError != nil { log.Fatal("MySQL Error: ", DBError) } MySql.SetLogging(false) defer MySql.Close() router := setupRouter() router.Run() // listen and serve on 0.0.0.0:8080 }الآن همه چی درسته ولی فایلی برای خوندن وجود نداره، باید فایل .env به پروژه اضافه کنیم ولی چون ممکنه کانفیگ هرکس تو سیستم خودش با دیگری فرق داشته باشه ما فایل به اسم .env.testing درست می‌کنیم و فایل .env تو گیت ایگنور میذاریم تاهرکس بعد کلون کردن پروژه فایل به .env تغییر نام بده و شخصی سازی کنه، پس به این صورت متغییرها تو فایل .env.testing معرفی می‌کنیم:# MySQL Config MYSQL_DATABASE=hesab_fun MYSQL_ADDRESS=localhost MYSQL_USERNAME=root MYSQL_PASSWORD=123456 MYSQL_PORT=3306همینطور فایل .gitignore به این صورت تغییر میدیم:vendor .idea hesabFun .envالآن رو سیستم MySQL نصب کنید به راحتی کانکت میشه البته یادتون نره دیتابیسی با اسم hesub_fun درست کنید، حالا باید بریم سراغ ساخت جدول‌های دیتابیس، برای این کار از مایگریشن استفاده میکنیم و هیچ‌وقت دستی دیتابیس دستکاری نمی‌کنیم.من از مایگریشن در کامندلاین استفاده میکنم، ترجیح میدم پروژه خیلی سنگین نکنم و چیزایی که نیاز نیست بهش اضافه نکنم، اگه داکیومنتش خونده باشید متوجه می‌شید برای نصبش باید دستور go get -v github.com/rubenv/sql-migrate/... اجرا کنید.حالا براش فایل کانفیگی با اسم dbconfig.yml ایجاد می‌کنیم:development: dialect: mysql datasource: ${MYSQL_USERNAME}:${MYSQL_PASSWORD}@tcp(${MYSQL_ADDRESS}:${MYSQL_PORT})/$MYSQL_DATABASE?charset=utf8&parseTime=True&loc=Local dir: ./migrations table: migrations seed: dialect: mysql datasource: ${MYSQL_USERNAME}:${MYSQL_PASSWORD}@tcp(${MYSQL_ADDRESS}:${MYSQL_PORT})/$MYSQL_DATABASE?charset=utf8&parseTime=True&loc=Local dir: ./seeds table: seedsمیریم تو روت پروژه و فولدرهای migrations و seeds می‌سازیم، با دستور sql-migrate new create_users_table جدول کاربران ایجاد می‌کنیم.حالا اگه بریم تو فولدر migrations فایل جدول کاربران می‌بینیم، محتوای فایل به همچین چیزی تغییر میدیم:-- +migrate Up CREATE TABLE `users` ( `id` int(10) UNSIGNED NOT NULL, `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `deleted_at` timestamp NULL DEFAULT null, `name` varchar(255) NOT NULL DEFAULT '', `email` varchar(255) NOT NULL DEFAULT '', `mobile` varchar(255) NOT NULL DEFAULT '', `password` varchar(255) DEFAULT NULL, `status` enum('pending','active','block') NOT NULL DEFAULT 'pending', `type` enum('user','admin','god') NOT NULL DEFAULT 'user', `remember_token` varchar(255) DEFAULT NULL, `sms_token` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ALTER TABLE `users` ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `email` (`email`,`mobile`); ALTER TABLE `users` MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT; COMMIT; -- +migrate Down DROP TABLE `users`;حالا با دستور sql-migrate new -env=seed create_user فایل جدیدی برای ساخت یوزر تست ایجاد می‌کنیم با همچین محتوایی:-- +migrate Up INSERT INTO `users` ( `created_at`, `updated_at`, `deleted_at`, `name`, `email`, `mobile`, `password`, `status`, `type`, `remember_token`, `sms_token`) VALUES ('2018-02-04 18:10:59', '2018-02-04 18:10:59', null, 'عرفان', '', '09111111111', '25d55ad283aa400af464c76d713c07ad', 'active', 'user', '', 0); -- +migrate Down DELETE FROM `users` WHERE `users`.`mobile` = '09111111111';خب حالا میخوایم میخوایم جدول ساخته بشه و دیتای تست بهش وارد بشه، قبل هرچیزی باید متغییرهای دیتابیس به سیستم مون اضافه کنیم، تو مک به این صورت عمل میکنیم. اول فایل .bash_profile باز میکنیم:nano ~/.bash_profileبعد محتوای زیر بیش اضافه می‌کنیم:export MYSQL_DATABASE=hesab_fun export MYSQL_ADDRESS=localhost export MYSQL_USERNAME=root export MYSQL_PASSWORD= export MYSQL_PORT=3306توجه کنید اگر تنظیمات دیتابیس شما غیر اینه، حتما تو فایل بالا تغییرش بدید.حالا کافیه تو روت پروژه دستور sql-migrate up بزنیم تا جدول users ایجاد بشه، برای اضافه کردن دیتای تست دستور sql-migrate up -env=seed میزنیم و دیتا به جدول کاربران اضافه میشه.تا اینجا همه چی بی نقصه، حالا باید بریم سراغ تست اپ، فایل .gitlab-ci.yml باز میکنیم و به این صورت تغییرش میدیم:image: golang:1.10 stages: - build - test services: - mysql:latest variables: MYSQL_DATABASE: hesab_fun MYSQL_ROOT_PASSWORD: 123456 MYSQL_ADDRESS: mysql MYSQL_PORT: 3306 MYSQL_PASSWORD: 123456 MYSQL_USERNAME: root before_script: - curl https://glide.sh/get | sh - mkdir -p /go/src/gitlab.com/ - cp -r /builds/erfun /go/src/gitlab.com/erfun - cd /go/src/gitlab.com/erfun/hesabFun - glide install - go get github.com/rubenv/sql-migrate/... - sql-migrate up - sql-migrate up -env=seed build-project: stage: build script: - go build test-project: stage: test script: - go test -v -coverاول از همه سرویس MySQL اضافه کردیم، بعد متغییرها دیتابیس اضافه کردیم، در آخر هم مایگریشن نصب و اجرا کردیم.اگه به نظرتون پیچیده شد، توصیه میکنیم کامیت‌ها تو گیت لب چک کنید و با دقت بخونید. بعد هر پست کدها کامیت می‌کنم.