Browse Source

Shop basket, shop orders db migration, fix cypress reset action, optimization

Vova Tkach 5 years ago
parent
commit
03e1beae83

+ 45 - 0
basket.go

@@ -0,0 +1,45 @@
+package main
+
+import (
+	"fmt"
+	"time"
+
+	"golang-fave/engine/basket"
+)
+
+func basket_clean_do(sb *basket.Basket, stop chan bool) {
+	sb.Cleanup()
+}
+
+func basket_clean_start(sb *basket.Basket) (chan bool, chan bool) {
+	ch := make(chan bool)
+	stop := make(chan bool)
+
+	go func() {
+		for {
+			select {
+			case <-time.After(30 * time.Minute):
+				// Cleanup every 30 minutes
+				basket_clean_do(sb, stop)
+			case <-ch:
+				ch <- true
+				return
+			}
+		}
+	}()
+	return ch, stop
+}
+
+func basket_clean_stop(ch, stop chan bool) {
+	for {
+		select {
+		case stop <- true:
+		case ch <- true:
+			<-ch
+			return
+		case <-time.After(3 * time.Second):
+			fmt.Println("Basket error: force exit by timeout after 3 seconds")
+			return
+		}
+	}
+}

+ 17 - 2
engine/basket/basket.go

@@ -121,6 +121,22 @@ func (this *Basket) Remove(p *SBParam, product_id int) string {
 	return (&dResponse{IsError: false, Msg: "basket_product_remove", Message: ""}).String()
 }
 
+func (this *Basket) ClearBasket(p *SBParam) {
+	if p.Host == "" || p.SessionId == "" {
+		return
+	}
+
+	this.Lock()
+	defer this.Unlock()
+
+	if h, ok := this.hosts[p.Host]; ok == true {
+		if s, ok := h.sessions[p.SessionId]; ok == true {
+			s.Preload(p)
+			s.ClearBasket(p)
+		}
+	}
+}
+
 func (this *Basket) ProductsCount(p *SBParam) int {
 	if p.Host != "" && p.SessionId != "" {
 		this.Lock()
@@ -136,8 +152,7 @@ func (this *Basket) ProductsCount(p *SBParam) int {
 	return 0
 }
 
-// TODO: run it by go routine time by time
-func (this *Basket) Cleanup(p *SBParam) {
+func (this *Basket) Cleanup() {
 	this.Lock()
 	defer this.Unlock()
 

+ 4 - 0
engine/basket/session.go

@@ -349,6 +349,10 @@ func (this *session) Remove(p *SBParam, product_id int) {
 	}
 }
 
+func (this *session) ClearBasket(p *SBParam) {
+	this.Products = map[int]*product{}
+}
+
 func (this *session) ProductsCount() int {
 	return this.TotalCount
 }

+ 25 - 5
main.go

@@ -111,14 +111,17 @@ func main() {
 	smtp_cl_ch, smtp_cl_stop := smtp_start(consts.ParamWwwDir, mpool)
 	defer smtp_stop(smtp_cl_ch, smtp_cl_stop)
 
-	// Init cache blocks
-	cbs := cblocks.New()
-
 	// Shop basket
 	sb := basket.New()
+	sb_cl_ch, sb_cl_stop := basket_clean_start(sb)
+	defer basket_clean_stop(sb_cl_ch, sb_cl_stop)
+
+	// Init cache blocks
+	cbs := cblocks.New()
 
 	// Init and start web server
-	bootstrap.Start(lg.Handler, fmt.Sprintf("%s:%d", consts.ParamHost, consts.ParamPort), 9, consts.AssetsPath, func(w http.ResponseWriter, r *http.Request, o interface{}) {
+	server_address := fmt.Sprintf("%s:%d", consts.ParamHost, consts.ParamPort)
+	bootstrap.Start(lg.Handler, server_address, 9, consts.AssetsPath, func(w http.ResponseWriter, r *http.Request, o interface{}) {
 		w.Header().Set("Server", "fave.pro/"+consts.ServerVersion)
 	}, func(w http.ResponseWriter, r *http.Request, o interface{}) {
 		// Schema
@@ -205,7 +208,24 @@ func main() {
 
 		// Logic
 		if mp != nil {
-			if engine.Response(mp, sb, lg, mods, w, r, sess, cbs, host, port, curr_host, vhost_dir_config, vhost_dir_htdocs, vhost_dir_logs, vhost_dir_template, vhost_dir_tmp) {
+			if engine.Response(
+				mp,
+				sb,
+				lg,
+				mods,
+				w,
+				r,
+				sess,
+				cbs,
+				host,
+				port,
+				curr_host,
+				vhost_dir_config,
+				vhost_dir_htdocs,
+				vhost_dir_logs,
+				vhost_dir_template,
+				vhost_dir_tmp,
+			) {
 				return
 			}
 		}

+ 2 - 0
modules/module_index_act_cypress.go

@@ -48,6 +48,8 @@ func (this *Modules) RegisterAction_IndexCypressReset() *Action {
 				shop_filter_product_values,
 				shop_filters,
 				shop_filters_values,
+				shop_order_products,
+				shop_orders,
 				shop_product_images,
 				shop_products,
 				users

+ 88 - 1
modules/module_index_act_mysql_setup.go

@@ -256,6 +256,49 @@ func (this *Modules) RegisterAction_IndexMysqlSetup() *Action {
 			return
 		}
 
+		// Table: shop_order_products
+		if _, err = tx.Exec(
+			`CREATE TABLE shop_order_products (
+				id int(11) NOT NULL AUTO_INCREMENT COMMENT 'AI',
+				order_id int(11) NOT NULL COMMENT 'Order ID',
+				product_id int(11) NOT NULL COMMENT 'Product ID',
+				price float(8,2) NOT NULL COMMENT 'Product price',
+				quantity int(11) NOT NULL COMMENT 'Quantity',
+				PRIMARY KEY (id)
+			) ENGINE=InnoDB DEFAULT CHARSET=utf8;`,
+		); err != nil {
+			tx.Rollback()
+			wrap.MsgError(err.Error())
+			return
+		}
+
+		// Table: shop_orders
+		if _, err = tx.Exec(
+			`CREATE TABLE shop_orders (
+				id int(11) NOT NULL AUTO_INCREMENT COMMENT 'AI',
+				create_datetime datetime NOT NULL COMMENT 'Create date/time',
+				update_datetime datetime NOT NULL COMMENT 'Update date/time',
+				currency_id int(11) NOT NULL COMMENT 'Currency ID',
+				currency_name varchar(255) NOT NULL COMMENT 'Currency name',
+				currency_coefficient float(8,4) NOT NULL DEFAULT '1.0000' COMMENT 'Currency coefficient',
+				currency_code varchar(10) NOT NULL COMMENT 'Currency code',
+				currency_symbol varchar(5) NOT NULL COMMENT 'Currency symbol',
+				client_last_name varchar(64) NOT NULL COMMENT 'Client last name',
+				client_first_name varchar(64) NOT NULL COMMENT 'Client first name',
+				client_second_name varchar(64) NOT NULL DEFAULT '' COMMENT 'Client second name',
+				client_phone varchar(64) NOT NULL DEFAULT '' COMMENT 'Client phone',
+				client_email varchar(20) NOT NULL COMMENT 'Client email',
+				client_delivery_comment text NOT NULL COMMENT 'Client delivery comment',
+				client_order_comment text NOT NULL COMMENT 'Client order comment',
+				status int(1) NOT NULL COMMENT 'new/confirmed/canceled/inprogress/completed',
+				PRIMARY KEY (id)
+			) ENGINE=InnoDB DEFAULT CHARSET=utf8;`,
+		); err != nil {
+			tx.Rollback()
+			wrap.MsgError(err.Error())
+			return
+		}
+
 		// Table: shop_product_images
 		if _, err = tx.Exec(
 			`CREATE TABLE shop_product_images (
@@ -488,7 +531,7 @@ func (this *Modules) RegisterAction_IndexMysqlSetup() *Action {
 			return
 		}
 		if _, err = tx.Exec(
-			`INSERT INTO settings (name, value) VALUES ('database_version', '000000014');`,
+			`INSERT INTO settings (name, value) VALUES ('database_version', '000000015');`,
 		); err != nil {
 			tx.Rollback()
 			wrap.MsgError(err.Error())
@@ -786,6 +829,26 @@ func (this *Modules) RegisterAction_IndexMysqlSetup() *Action {
 			wrap.MsgError(err.Error())
 			return
 		}
+		if _, err = tx.Exec(`ALTER TABLE shop_orders ADD KEY FK_shop_orders_currency_id (currency_id);`); err != nil {
+			tx.Rollback()
+			wrap.MsgError(err.Error())
+			return
+		}
+		if _, err = tx.Exec(`ALTER TABLE shop_order_products ADD UNIQUE KEY order_product (order_id,product_id) USING BTREE;`); err != nil {
+			tx.Rollback()
+			wrap.MsgError(err.Error())
+			return
+		}
+		if _, err = tx.Exec(`ALTER TABLE shop_order_products ADD KEY FK_shop_order_products_order_id (order_id);`); err != nil {
+			tx.Rollback()
+			wrap.MsgError(err.Error())
+			return
+		}
+		if _, err = tx.Exec(`ALTER TABLE shop_order_products ADD KEY FK_shop_order_products_product_id (product_id);`); err != nil {
+			tx.Rollback()
+			wrap.MsgError(err.Error())
+			return
+		}
 		if _, err = tx.Exec(`ALTER TABLE shop_product_images ADD UNIQUE KEY product_filename (product_id,filename) USING BTREE;`); err != nil {
 			tx.Rollback()
 			wrap.MsgError(err.Error())
@@ -929,6 +992,30 @@ func (this *Modules) RegisterAction_IndexMysqlSetup() *Action {
 			wrap.MsgError(err.Error())
 			return
 		}
+		if _, err = tx.Exec(`
+			ALTER TABLE shop_orders ADD CONSTRAINT FK_shop_orders_currency_id
+			FOREIGN KEY (currency_id) REFERENCES shop_currencies (id) ON DELETE RESTRICT;
+		`); err != nil {
+			tx.Rollback()
+			wrap.MsgError(err.Error())
+			return
+		}
+		if _, err = tx.Exec(`
+			ALTER TABLE shop_order_products ADD CONSTRAINT FK_shop_order_products_order_id
+			FOREIGN KEY (order_id) REFERENCES shop_orders (id) ON DELETE RESTRICT;
+		`); err != nil {
+			tx.Rollback()
+			wrap.MsgError(err.Error())
+			return
+		}
+		if _, err = tx.Exec(`
+			ALTER TABLE shop_order_products ADD CONSTRAINT FK_shop_order_products_product_id
+			FOREIGN KEY (product_id) REFERENCES shop_products (id) ON DELETE RESTRICT;
+		`); err != nil {
+			tx.Rollback()
+			wrap.MsgError(err.Error())
+			return
+		}
 		if _, err = tx.Exec(`
 			ALTER TABLE shop_product_images ADD CONSTRAINT FK_shop_product_images_product_id
 			FOREIGN KEY (product_id) REFERENCES shop_products (id) ON DELETE RESTRICT;

+ 1 - 0
support/migrate/000000001.go

@@ -20,4 +20,5 @@ var Migrations = map[string]func(*sqlw.DB, string) error{
 	"000000012": Migrate_000000012,
 	"000000013": Migrate_000000013,
 	"000000014": Migrate_000000014,
+	"000000015": Migrate_000000015,
 }

+ 82 - 0
support/migrate/000000015.go

@@ -0,0 +1,82 @@
+package migrate
+
+import (
+	"golang-fave/engine/sqlw"
+)
+
+func Migrate_000000015(db *sqlw.DB, host string) error {
+	// Table: shop_orders
+	if _, err := db.Exec(
+		`CREATE TABLE shop_orders (
+			id int(11) NOT NULL AUTO_INCREMENT COMMENT 'AI',
+			create_datetime datetime NOT NULL COMMENT 'Create date/time',
+			update_datetime datetime NOT NULL COMMENT 'Update date/time',
+			currency_id int(11) NOT NULL COMMENT 'Currency ID',
+			currency_name varchar(255) NOT NULL COMMENT 'Currency name',
+			currency_coefficient float(8,4) NOT NULL DEFAULT '1.0000' COMMENT 'Currency coefficient',
+			currency_code varchar(10) NOT NULL COMMENT 'Currency code',
+			currency_symbol varchar(5) NOT NULL COMMENT 'Currency symbol',
+			client_last_name varchar(64) NOT NULL COMMENT 'Client last name',
+			client_first_name varchar(64) NOT NULL COMMENT 'Client first name',
+			client_second_name varchar(64) NOT NULL DEFAULT '' COMMENT 'Client second name',
+			client_phone varchar(64) NOT NULL DEFAULT '' COMMENT 'Client phone',
+			client_email varchar(20) NOT NULL COMMENT 'Client email',
+			client_delivery_comment text NOT NULL COMMENT 'Client delivery comment',
+			client_order_comment text NOT NULL COMMENT 'Client order comment',
+			status int(1) NOT NULL COMMENT 'new/confirmed/canceled/inprogress/completed',
+			PRIMARY KEY (id)
+		) ENGINE=InnoDB DEFAULT CHARSET=utf8;`,
+	); err != nil {
+		return err
+	}
+
+	// Table: shop_order_products
+	if _, err := db.Exec(
+		`CREATE TABLE shop_order_products (
+			id int(11) NOT NULL AUTO_INCREMENT COMMENT 'AI',
+			order_id int(11) NOT NULL COMMENT 'Order ID',
+			product_id int(11) NOT NULL COMMENT 'Product ID',
+			price float(8,2) NOT NULL COMMENT 'Product price',
+			quantity int(11) NOT NULL COMMENT 'Quantity',
+			PRIMARY KEY (id)
+		) ENGINE=InnoDB DEFAULT CHARSET=utf8;`,
+	); err != nil {
+		return err
+	}
+
+	// Indexes
+	if _, err := db.Exec(`ALTER TABLE shop_orders ADD KEY FK_shop_orders_currency_id (currency_id);`); err != nil {
+		return err
+	}
+	if _, err := db.Exec(`ALTER TABLE shop_order_products ADD UNIQUE KEY order_product (order_id,product_id) USING BTREE;`); err != nil {
+		return err
+	}
+	if _, err := db.Exec(`ALTER TABLE shop_order_products ADD KEY FK_shop_order_products_order_id (order_id);`); err != nil {
+		return err
+	}
+	if _, err := db.Exec(`ALTER TABLE shop_order_products ADD KEY FK_shop_order_products_product_id (product_id);`); err != nil {
+		return err
+	}
+
+	// References
+	if _, err := db.Exec(`
+		ALTER TABLE shop_orders ADD CONSTRAINT FK_shop_orders_currency_id
+		FOREIGN KEY (currency_id) REFERENCES shop_currencies (id) ON DELETE RESTRICT;
+	`); err != nil {
+		return err
+	}
+	if _, err := db.Exec(`
+		ALTER TABLE shop_order_products ADD CONSTRAINT FK_shop_order_products_order_id
+		FOREIGN KEY (order_id) REFERENCES shop_orders (id) ON DELETE RESTRICT;
+	`); err != nil {
+		return err
+	}
+	if _, err := db.Exec(`
+		ALTER TABLE shop_order_products ADD CONSTRAINT FK_shop_order_products_product_id
+		FOREIGN KEY (product_id) REFERENCES shop_products (id) ON DELETE RESTRICT;
+	`); err != nil {
+		return err
+	}
+
+	return nil
+}

+ 34 - 0
support/schema.sql

@@ -88,6 +88,33 @@ CREATE TABLE shop_filters_values (
 	name varchar(255) NOT NULL COMMENT 'Value name',
 	PRIMARY KEY (id)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE shop_order_products (
+	id int(11) NOT NULL AUTO_INCREMENT COMMENT 'AI',
+	order_id int(11) NOT NULL COMMENT 'Order ID',
+	product_id int(11) NOT NULL COMMENT 'Product ID',
+	price float(8,2) NOT NULL COMMENT 'Product price',
+	quantity int(11) NOT NULL COMMENT 'Quantity',
+	PRIMARY KEY (id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE shop_orders (
+	id int(11) NOT NULL AUTO_INCREMENT COMMENT 'AI',
+	create_datetime datetime NOT NULL COMMENT 'Create date/time',
+	update_datetime datetime NOT NULL COMMENT 'Update date/time',
+	currency_id int(11) NOT NULL COMMENT 'Currency ID',
+	currency_name varchar(255) NOT NULL COMMENT 'Currency name',
+	currency_coefficient float(8,4) NOT NULL DEFAULT '1.0000' COMMENT 'Currency coefficient',
+	currency_code varchar(10) NOT NULL COMMENT 'Currency code',
+	currency_symbol varchar(5) NOT NULL COMMENT 'Currency symbol',
+	client_last_name varchar(64) NOT NULL COMMENT 'Client last name',
+	client_first_name varchar(64) NOT NULL COMMENT 'Client first name',
+	client_second_name varchar(64) NOT NULL DEFAULT '' COMMENT 'Client second name',
+	client_phone varchar(64) NOT NULL DEFAULT '' COMMENT 'Client phone',
+	client_email varchar(20) NOT NULL COMMENT 'Client email',
+	client_delivery_comment text NOT NULL COMMENT 'Client delivery comment',
+	client_order_comment text NOT NULL COMMENT 'Client order comment',
+	status int(1) NOT NULL COMMENT 'new/confirmed/canceled/inprogress/completed',
+	PRIMARY KEY (id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 CREATE TABLE shop_product_images (
 	id int(11) NOT NULL AUTO_INCREMENT,
 	product_id int(11) NOT NULL,
@@ -151,6 +178,10 @@ ALTER TABLE shop_filter_product_values ADD KEY FK_shop_filter_product_values_fil
 ALTER TABLE shop_filters ADD KEY name (name);
 ALTER TABLE shop_filters_values ADD KEY FK_shop_filters_values_filter_id (filter_id);
 ALTER TABLE shop_filters_values ADD KEY name (name);
+ALTER TABLE shop_orders ADD KEY FK_shop_orders_currency_id (currency_id);
+ALTER TABLE shop_order_products ADD UNIQUE KEY order_product (order_id,product_id) USING BTREE;
+ALTER TABLE shop_order_products ADD KEY FK_shop_order_products_order_id (order_id);
+ALTER TABLE shop_order_products ADD KEY FK_shop_order_products_product_id (product_id);
 ALTER TABLE shop_product_images ADD UNIQUE KEY product_filename (product_id,filename) USING BTREE;
 ALTER TABLE shop_product_images ADD KEY FK_shop_product_images_product_id (product_id);
 ALTER TABLE shop_products ADD UNIQUE KEY alias (alias);
@@ -174,6 +205,9 @@ ALTER TABLE shop_cats ADD CONSTRAINT FK_shop_cats_user FOREIGN KEY (user) REFERE
 ALTER TABLE shop_filter_product_values ADD CONSTRAINT FK_shop_filter_product_values_product_id FOREIGN KEY (product_id) REFERENCES shop_products (id) ON DELETE RESTRICT;
 ALTER TABLE shop_filter_product_values ADD CONSTRAINT FK_shop_filter_product_values_filter_value_id FOREIGN KEY (filter_value_id) REFERENCES shop_filters_values (id) ON DELETE RESTRICT;
 ALTER TABLE shop_filters_values ADD CONSTRAINT FK_shop_filters_values_filter_id FOREIGN KEY (filter_id) REFERENCES shop_filters (id) ON DELETE RESTRICT;
+ALTER TABLE shop_orders ADD CONSTRAINT FK_shop_orders_currency_id FOREIGN KEY (currency_id) REFERENCES shop_currencies (id) ON DELETE RESTRICT;
+ALTER TABLE shop_order_products ADD CONSTRAINT FK_shop_order_products_order_id FOREIGN KEY (order_id) REFERENCES shop_orders (id) ON DELETE RESTRICT;
+ALTER TABLE shop_order_products ADD CONSTRAINT FK_shop_order_products_product_id FOREIGN KEY (product_id) REFERENCES shop_products (id) ON DELETE RESTRICT;
 ALTER TABLE shop_product_images ADD CONSTRAINT FK_shop_product_images_product_id FOREIGN KEY (product_id) REFERENCES shop_products (id) ON DELETE RESTRICT;
 ALTER TABLE shop_products ADD CONSTRAINT FK_shop_products_user FOREIGN KEY (user) REFERENCES users (id) ON DELETE RESTRICT;
 ALTER TABLE shop_products ADD CONSTRAINT FK_shop_products_currency FOREIGN KEY (currency) REFERENCES shop_currencies (id) ON DELETE RESTRICT;