package postgres import ( "context" "errors" "fmt" rs "github.com/danilsolovyov/reflectgostructv1" "github.com/jackc/pgx/v4/pgxpool" "penahub.gitlab.yandexcloud.net/backend/templategen/dal/model" "strconv" "strings" "time" ) type YaDisk struct { conn *pgxpool.Pool } func InitYaDisk(ctx context.Context, conn *pgxpool.Pool) *YaDisk { d := &YaDisk{conn: conn} err := d.init(ctx) if err != nil { //glg.Error("ErrInitYaDisk", err) return nil } return d } func (d *YaDisk) init(ctx context.Context) error { s := rs.PsqlTagToSql(&model.YaDisk{}) sql := fmt.Sprintf("CREATE TABLE IF NOT EXISTS \"YaDisk\" (%v);", s) _, err := d.conn.Exec(ctx, sql) return err } func (d *YaDisk) Insert(ctx context.Context, record *model.YaDisk) (int, error) { now := time.Now().UTC() record.CreatedAt = now record.UpdatedAt = now record.IsDeleted = false conn, err := d.conn.Acquire(ctx) if err != nil { conn.Release() return 0, err } //Find YaDisk by user_id sql := fmt.Sprintf("SELECT id FROM \"YaDisk\" WHERE user_id = '%v'", record.UserID) var foundID int err = conn.QueryRow(ctx, sql).Scan(&foundID) if err != nil { if err.Error() != ErrorNotFound.Error() { return 0, err } } if foundID > 0 { fmt.Println("YaDisk already exists", foundID) err = errors.New("YaDisk already exists") return 0, err } tags, values := rs.GetPsqlTagsAndValues(record) sql = fmt.Sprintf("INSERT INTO \"YaDisk\" (%v) VALUES (%v) RETURNING id;", tags, values) var id int err = conn.QueryRow(ctx, sql).Scan(&id) conn.Release() if err != nil { return 0, err } return id, nil } func (d *YaDisk) InsertOrUpdate(ctx context.Context, record *model.YaDisk) (string, error) { now := time.Now().UTC() record.CreatedAt = now record.UpdatedAt = now record.IsDeleted = false conn, err := d.conn.Acquire(ctx) if err != nil { conn.Release() return "", err } //Find YaDisk by user_id sql := fmt.Sprintf("SELECT id FROM \"YaDisk\" WHERE user_id = '%v'", record.UserID) var foundID int err = conn.QueryRow(ctx, sql).Scan(&foundID) if err != nil { fmt.Println("errr", err) if err.Error() != ErrorNotFound.Error() { return "", err } } tags, values := rs.GetPsqlTagsAndValues(record) var id int if foundID > 0 { sql = fmt.Sprintf("UPDATE \"YaDisk\" SET (%v) = (%v) WHERE id = %v;", tags, values, record.ID) id = foundID } else { sql = fmt.Sprintf("INSERT INTO \"YaDisk\" (%v) VALUES (%v) RETURNING id;", tags, values) } err = conn.QueryRow(ctx, sql).Scan(&id) conn.Release() if err != nil { return "", err } return strconv.Itoa(id), nil } func (d *YaDisk) GetByID(ctx context.Context, id string) (*model.YaDisk, error) { var result model.YaDisk conn, err := d.conn.Acquire(ctx) if err != nil { conn.Release() return nil, err } sql := fmt.Sprintf("SELECT * FROM \"YaDisk\" WHERE id = %v", id) rows, err := conn.Query(ctx, sql) conn.Release() if err != nil { return nil, err } for rows.Next() { err = rows.Scan(&result.ID, &result.UserID, &result.AccessToken, &result.TemplateFolder, &result.SaveFolder, &result.ExpiresIn, &result.IsDeleted, &result.CreatedAt, &result.UpdatedAt) if err != nil { return nil, err } } return &result, err } func (d *YaDisk) GetByFilter(ctx context.Context, start, count int, needle map[string]string) ([]model.YaDisk, error) { var result []model.YaDisk conn, err := d.conn.Acquire(ctx) if err != nil { conn.Release() return nil, err } needleToSql := "" if len(needle) > 0 { needleToSql += " AND " i := 0 for k, v := range needle { v = strings.ReplaceAll(v, "'", "''") needleToSql += fmt.Sprintf("%v = %v", k, v) if i < len(needle) { needleToSql += " AND " } i++ } } sql := fmt.Sprintf("SELECT * FROM \"YaDisk\" WHERE (id >= %v %v) ORDER BY id LIMIT %v;", start, needleToSql, count, ) rows, err := conn.Query(ctx, sql) conn.Release() if err != nil { return nil, err } if rows == nil { err = ErrorGotEmptyRow return nil, err } for rows.Next() { var u model.YaDisk err = rows.Scan(&u.ID, &u.UserID, &u.AccessToken, &u.TemplateFolder, &u.SaveFolder, &u.ExpiresIn, &u.IsDeleted, &u.CreatedAt, &u.UpdatedAt) if err != nil { return nil, err } result = append(result, u) } return result, nil } func (d *YaDisk) UpdateByID(ctx context.Context, record *model.YaDisk) error { record.UpdatedAt = time.Now().UTC() conn, err := d.conn.Acquire(ctx) if err != nil { conn.Release() return err } tags, values := rs.GetPsqlTagsAndValues(record) sql := fmt.Sprintf("UPDATE \"YaDisk\" SET (%v) = (%v) WHERE id = %v;", tags, values, record.ID) err = conn.QueryRow(ctx, sql).Scan() conn.Release() if err != nil { return err } return nil } func (d *YaDisk) DeleteByID(ctx context.Context, id string) error { conn, err := d.conn.Acquire(ctx) if err != nil { conn.Release() return err } sql := fmt.Sprintf("UPDATE \"YaDisk\" SET is_deleted = true WHERE id = %v", id) err = conn.QueryRow(ctx, sql).Scan() conn.Release() if err != nil { return err } return nil }