eintopf.info@v0.13.16/service/notification/store_sql.go (about)

     1  // Copyright (C) 2024 The Eintopf authors
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <https://www.gnu.org/licenses/>.
    15  
    16  package notification
    17  
    18  import (
    19  	"context"
    20  
    21  	"eintopf.info/internal/crud"
    22  	"eintopf.info/service/dbmigration"
    23  	"github.com/jmoiron/sqlx"
    24  )
    25  
    26  // NewSqlStore returns a new sql store for notifications.
    27  func NewSqlStore(db *sqlx.DB, migrationService dbmigration.Service) (*SqlStore, error) {
    28  	store := &SqlStore{
    29  		db,
    30  		migrationService,
    31  		crud.NewSqlStore(db, notificationTable, NotifictaionFromNewNotification, nil),
    32  	}
    33  	if err := store.runMigrations(context.Background()); err != nil {
    34  		return nil, err
    35  	}
    36  	return store, nil
    37  }
    38  
    39  type SqlStore struct {
    40  	db               *sqlx.DB
    41  	migrationService dbmigration.Service
    42  
    43  	*crud.SqlStore[NewNotification, Notification, Filters]
    44  }
    45  
    46  func (s *SqlStore) runMigrations(ctx context.Context) error {
    47  	return s.migrationService.RunMigrations(ctx, []dbmigration.Migration{
    48  		dbmigration.NewMigration("createNotificationTable", s.createNotificationTable, nil),
    49  		dbmigration.NewMigration("addNotificationLinkFields", s.addotificationLinkFields, nil),
    50  	})
    51  }
    52  
    53  func (s *SqlStore) createNotificationTable(ctx context.Context) error {
    54  	_, err := s.db.ExecContext(ctx, `
    55          CREATE TABLE IF NOT EXISTS notifications (
    56              id VARCHAR(32) NOT NULL PRIMARY KEY UNIQUE,
    57              created_at TIMESTAMP,
    58              user_id VARCHAR(32) NOT NULL,
    59              subject TEXT NOT NULL,
    60              message TEXT NOT NULL,
    61              viewed BOOLEAN DEFAULT FALSE
    62          );
    63      `)
    64  	return err
    65  }
    66  func (s *SqlStore) addotificationLinkFields(ctx context.Context) error {
    67  	_, err := s.db.ExecContext(ctx, `
    68  		ALTER TABLE notifications ADD COLUMN link_title TEXT NOT NULL;
    69  		ALTER TABLE notifications ADD COLUMN link_url TEXT NOT NULL;
    70  		UPDATE notifications SET link_title="", link_url="";
    71      `)
    72  	return err
    73  }
    74  
    75  var notificationTable = crud.SqlTable[Filters]{
    76  	IDField:        "id",
    77  	Table:          "notifications",
    78  	Fields:         []string{"id", "created_at", "user_id", "subject", "message", "link_title", "link_url", "viewed"},
    79  	SortableFields: []string{"id", "created_at", "user_id", "subject", "viewed"},
    80  }
    81  
    82  // NewSqlStore returns a new sql db event store.
    83  func NewSettingsSqlStore(db *sqlx.DB, migrationService dbmigration.Service) (*SettingsSqlStore, error) {
    84  	store := &SettingsSqlStore{
    85  		db,
    86  		migrationService,
    87  		crud.NewSqlStore(db, settingsTable, SettingsFromNewSettings, nil),
    88  	}
    89  	if err := store.runMigrations(context.Background()); err != nil {
    90  		return nil, err
    91  	}
    92  	return store, nil
    93  }
    94  
    95  type SettingsSqlStore struct {
    96  	db               *sqlx.DB
    97  	migrationService dbmigration.Service
    98  
    99  	*crud.SqlStore[NewSettings, Settings, SettingsFilters]
   100  }
   101  
   102  func (s *SettingsSqlStore) runMigrations(ctx context.Context) error {
   103  	return s.migrationService.RunMigrations(ctx, []dbmigration.Migration{
   104  		dbmigration.NewMigration("createNotificationSettingsTable", s.createSettingsTable, nil),
   105  	})
   106  }
   107  
   108  func (s *SettingsSqlStore) createSettingsTable(ctx context.Context) error {
   109  	_, err := s.db.ExecContext(ctx, `
   110          CREATE TABLE IF NOT EXISTS notification_settings (
   111              user_id VARCHAR(32) NOT NULL PRIMARY KEY UNIQUE,
   112              email BOOLEAN DEFAULT FALSE
   113          );
   114      `)
   115  	return err
   116  }
   117  
   118  var settingsTable = crud.SqlTable[SettingsFilters]{
   119  	IDField:        "user_id",
   120  	Table:          "notification_settings",
   121  	Fields:         []string{"user_id", "email"},
   122  	SortableFields: []string{"user_id", "email"},
   123  }