package datamysql import ( "database/sql" "fmt" "bitbucket.org/nemt/nemt-portal-api/domain/entity" "bitbucket.org/nemt/nemt-portal-api/infra/errors" uuid "github.com/satori/go.uuid" ) // visitRepo maps methods to database type notificationRepo struct { conn executor } func newNotificationRepo(conn executor) *notificationRepo { return ¬ificationRepo{ conn: conn, } } func (c *notificationRepo) Create(notification entity.Notification) (entity.Notification, error) { const ( statusQuery = `SELECT a.contact_type_id, b.ride_id, c.user_id, d.user_id created_user_id FROM tab_contact_type a, tab_ride b, tab_user c, tab_user d WHERE a.key = ? AND b.ride_uuid = ? AND c.user_uuid = ? AND d.user_uuid = ?;` query = `INSERT INTO tab_notification(notification_uuid, ride_id, user_id, contact_type_id, contact, message, created_user_id, readed, notificaton_type) VALUES(?, ?, ?, ?, ?, ?, ?, 0, ?);` ) retVal := notification UUID, _ := uuid.NewV4() retVal.UUID = UUID.String() row := c.conn.QueryRow(statusQuery, retVal.Type, retVal.Ride.UUID, retVal.User.UUID, retVal.CreatedUser.UUID) if err := row.Scan(&retVal.TypeID, &retVal.Ride.ID, &retVal.User.ID, &retVal.CreatedUser.ID); err != nil { fmt.Println("Error to get base data: ", err.Error()) return retVal, err } results, err := c.conn.Exec(query, retVal.UUID, retVal.Ride.ID, retVal.User.ID, retVal.TypeID, retVal.Subject, retVal.Message, retVal.CreatedUser.ID, retVal.MessageType) if err != nil { return retVal, err } retVal.ID, err = results.LastInsertId() if err != nil { return retVal, err } return c.GetByID(retVal.ID) } func (c *notificationRepo) getQuery() string { return `SELECT a.notification_id, a.notification_uuid, a.ride_id, a.user_id, c.user_uuid, c.name user_name, CASE WHEN b.key = 'sms' THEN e.phone_number WHEN b.key = 'email' THEN e.email WHEN b.key = 'app' THEN c.user_uuid END to_address, CASE WHEN b.key = 'sms' THEN f.phone_number WHEN b.key = 'email' THEN f.email WHEN b.key = 'app' THEN d.user_uuid END from_address, a.contact_type_id, b.key contact_type_key, a.contact, a.message, a.create_at, a.readed, d.user_id created_user_id, d.user_uuid created_user_uuid, d.name created_user_name, a.notificaton_type FROM tab_notification a INNER JOIN tab_contact_type b ON a.contact_type_id = b.contact_type_id INNER JOIN tab_user c ON a.user_id = c.user_id INNER JOIN tab_user d ON a.created_user_id = d.user_id INNER JOIN tab_login e ON c.user_id = e.user_id INNER JOIN tab_login f ON d.user_id = f.user_id` } func (c *notificationRepo) GetLastNotificationFromPhoneNumber(notificationType string, phoneNumber string, status string) (entity.Notification, error) { const ( whereClause = ` WHERE a.notificaton_type = ? AND e.phone_number = ? AND b.key = ? ORDER BY a.notification_id DESC LIMIT 1;` ) finalQuery := c.getQuery() + whereClause return c.parseEntity(c.conn.QueryRow(finalQuery, notificationType, phoneNumber, status)) } func (c *notificationRepo) GetByUserUUIDAndReadStatus(userUUID string, status string, isRead bool) ([]entity.Notification, error) { return c.parseSet(c.conn.Query(c.getQuery()+" WHERE a.readed = ? AND b.key = ? AND c.user_uuid = ?; ", isRead, status, userUUID)) } func (c *notificationRepo) GetByUserUUID(userUUID string, status string) ([]entity.Notification, error) { return c.parseSet(c.conn.Query(c.getQuery()+" WHERE b.key = ? AND c.user_uuid = ?; ", status, userUUID)) } func (c *notificationRepo) ReadStatus(notificationUUID string, isRead bool) error { const query = "UPDATE tab_notification SET readed = ? WHERE notification_uuid = ?" _, err := c.conn.Exec(query, isRead, notificationUUID) return err } func (c *notificationRepo) GetByID(ID int64) (entity.Notification, error) { return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE a.notification_id = ?; ", ID)) } // parseSet parses a result set result to an entity array func (c *notificationRepo) parseSet(rows *sql.Rows, err error) ([]entity.Notification, error) { if err != nil { return nil, errors.Wrap(err) } result := make([]entity.Notification, 0) for rows.Next() { entity, err := c.parseEntity(rows) if err != nil { return nil, errors.Wrap(err) } result = append(result, entity) } return result, nil } // parseEntity parses a result to an entity func (c *notificationRepo) parseEntity(row scanner) (retVal entity.Notification, err error) { err = row.Scan( &retVal.ID, &retVal.UUID, &retVal.Ride.ID, &retVal.User.ID, &retVal.User.UUID, &retVal.User.Name, &retVal.To, &retVal.From, &retVal.TypeID, &retVal.Type, &retVal.Subject, &retVal.Message, &retVal.Created, &retVal.Read, &retVal.CreatedUser.ID, &retVal.CreatedUser.UUID, &retVal.CreatedUser.Name, &retVal.MessageType) return retVal, errors.Wrap(err) }