44 "context"
55 "database/sql"
66 "errors"
7+ "fmt"
78 "time"
89
910 "github.com/go-sql-driver/mysql"
@@ -15,46 +16,108 @@ const hashingLockName = "36444143-1ace-4dbf-891c-cc505911497e"
1516
1617var ErrMessageNotFound = gorm .ErrRecordNotFound
1718var ErrMessageAlreadyExists = errors .New ("duplicate id" )
19+ var ErrMultipleMessagesFound = errors .New ("multiple messages found" )
1820
1921type repository struct {
2022 db * gorm.DB
2123}
2224
23- func (r * repository ) SelectPending (deviceID string ) (messages []Message , err error ) {
24- err = r .db .
25- Where ("device_id = ? AND state = ?" , deviceID , ProcessingStatePending ).
26- Order ("priority DESC, id DESC" ).
27- Limit (100 ).
28- Preload ("Recipients" ).
29- Find (& messages ).
30- Error
25+ func (r * repository ) Select (filter MessagesSelectFilter , options MessagesSelectOptions ) ([]Message , int64 , error ) {
26+ query := r .db .Model (& Message {})
3127
32- return
33- }
28+ // Apply date range filter
29+ if ! filter .StartDate .IsZero () {
30+ query = query .Where ("messages.created_at >= ?" , filter .StartDate )
31+ }
32+ if ! filter .EndDate .IsZero () {
33+ query = query .Where ("messages.created_at < ?" , filter .EndDate )
34+ }
35+
36+ // Apply ID filter
37+ if filter .ExtID != "" {
38+ query = query .Where ("messages.ext_id = ?" , filter .ExtID )
39+ }
40+
41+ // Apply user filter
42+ if filter .UserID != "" {
43+ query = query .
44+ Joins ("JOIN devices ON messages.device_id = devices.id" ).
45+ Where ("devices.user_id = ?" , filter .UserID )
46+ }
3447
35- func (r * repository ) Get (ID string , filter MessagesSelectFilter , options ... MessagesSelectOptions ) (message Message , err error ) {
36- query := r .db .Model (& message ).
37- Where ("ext_id = ?" , ID )
48+ // Apply state filter
49+ if filter .State != "" {
50+ query = query .Where ("messages.state = ?" , filter .State )
51+ }
3852
53+ // Apply device filter
3954 if filter .DeviceID != "" {
40- query = query .Where ("device_id = ?" , filter .DeviceID )
55+ query = query .Where ("messages. device_id = ?" , filter .DeviceID )
4156 }
4257
43- if len (options ) > 0 {
44- if options [0 ].WithRecipients {
45- query = query .Preload ("Recipients" )
46- }
47- if options [0 ].WithDevice {
48- query = query .Joins ("Device" )
49- }
50- if options [0 ].WithStates {
51- query = query .Preload ("States" )
52- }
58+ // Get total count
59+ var total int64
60+ if err := query .Count (& total ).Error ; err != nil {
61+ return nil , 0 , err
62+ }
63+
64+ // Apply pagination
65+ if options .Limit > 0 {
66+ query = query .Limit (options .Limit )
67+ }
68+ if options .Offset > 0 {
69+ query = query .Offset (options .Offset )
70+ }
71+
72+ // Apply ordering
73+ query = query .Order ("messages.priority DESC, messages.id DESC" )
74+
75+ // Preload related data
76+ if options .WithRecipients {
77+ query = query .Preload ("Recipients" )
78+ }
79+ if filter .UserID == "" && options .WithDevice {
80+ query = query .Joins ("Device" )
81+ }
82+ if options .WithStates {
83+ query = query .Preload ("States" )
84+ }
85+
86+ messages := make ([]Message , 0 , min (options .Limit , int (total )))
87+ if err := query .Find (& messages ).Error ; err != nil {
88+ return nil , 0 , fmt .Errorf ("can't select messages: %w" , err )
89+ }
90+
91+ return messages , total , nil
92+ }
93+
94+ func (r * repository ) SelectPending (deviceID string ) ([]Message , error ) {
95+ messages , _ , err := r .Select (MessagesSelectFilter {
96+ DeviceID : deviceID ,
97+ State : ProcessingStatePending ,
98+ }, MessagesSelectOptions {
99+ WithRecipients : true ,
100+ Limit : 100 ,
101+ })
102+
103+ return messages , err
104+ }
105+
106+ func (r * repository ) Get (filter MessagesSelectFilter , options MessagesSelectOptions ) (Message , error ) {
107+ messages , _ , err := r .Select (filter , options )
108+ if err != nil {
109+ return Message {}, fmt .Errorf ("can't get message: %w" , err )
110+ }
111+
112+ if len (messages ) == 0 {
113+ return Message {}, ErrMessageNotFound
53114 }
54115
55- err = query .Take (& message ).Error
116+ if len (messages ) > 1 {
117+ return Message {}, ErrMultipleMessagesFound
118+ }
56119
57- return
120+ return messages [ 0 ], nil
58121}
59122
60123func (r * repository ) Insert (message * Message ) error {
0 commit comments