@@ -5,57 +5,59 @@ import (
5
5
6
6
"github.com/jmoiron/sqlx"
7
7
"github.com/juju/errors"
8
- "github.com/lib/pq"
9
8
"github.com/nyaruka/goflow/assets"
10
9
null "gopkg.in/guregu/null.v3"
11
10
)
12
11
13
12
type ChannelID int
14
13
15
- // Channel is the mailman struct that represents channels
14
+ // Channel is the mailroom struct that represents channels
16
15
type Channel struct {
17
- id ChannelID
18
- uuid assets.ChannelUUID
19
- parent * assets.ChannelReference
20
- name string
21
- address string
22
- country null.String
23
- schemes []string
24
- roles []assets.ChannelRole
25
- prefixes []string
16
+ // inner struct for privacy and so we don't collide with method names
17
+ c struct {
18
+ ID ChannelID `json:"id"`
19
+ UUID assets.ChannelUUID `json:"uuid"`
20
+ Parent * assets.ChannelReference `json:"parent"`
21
+ Name string `json:"name"`
22
+ Address string `json:"address"`
23
+ Country null.String `json:"country"`
24
+ Schemes []string `json:"schemes"`
25
+ Roles []assets.ChannelRole `json:"roles"`
26
+ MatchPrefixes []string `json:"match_prefixes"`
27
+ }
26
28
}
27
29
28
30
// ID returns the id of this channel
29
- func (c * Channel ) ID () ChannelID { return c .id }
31
+ func (c * Channel ) ID () ChannelID { return c .c . ID }
30
32
31
33
// UUID returns the UUID of this channel
32
- func (c * Channel ) UUID () assets.ChannelUUID { return c .uuid }
34
+ func (c * Channel ) UUID () assets.ChannelUUID { return c .c . UUID }
33
35
34
36
// Name returns the name of this channel
35
- func (c * Channel ) Name () string { return c .name }
37
+ func (c * Channel ) Name () string { return c .c . Name }
36
38
37
39
// Address returns the name of this channel
38
- func (c * Channel ) Address () string { return c .address }
40
+ func (c * Channel ) Address () string { return c .c . Address }
39
41
40
42
// Country returns the contry code for this channel
41
- func (c * Channel ) Country () string { return c .country .String }
43
+ func (c * Channel ) Country () string { return c .c . Country .String }
42
44
43
45
// Schemes returns the schemes this channel supports
44
- func (c * Channel ) Schemes () []string { return c .schemes }
46
+ func (c * Channel ) Schemes () []string { return c .c . Schemes }
45
47
46
48
// Roles returns the roles this channel supports
47
- func (c * Channel ) Roles () []assets.ChannelRole { return c .roles }
49
+ func (c * Channel ) Roles () []assets.ChannelRole { return c .c . Roles }
48
50
49
51
// MatchPrefixes returns the prefixes we should also match when determining channel affinity
50
- func (c * Channel ) MatchPrefixes () []string { return c .prefixes }
52
+ func (c * Channel ) MatchPrefixes () []string { return c .c . MatchPrefixes }
51
53
52
54
// Parent returns the UUID of the parent channel to this channel
53
55
// TODO: add support for parent channels
54
- func (c * Channel ) Parent () * assets.ChannelReference { return c .parent }
56
+ func (c * Channel ) Parent () * assets.ChannelReference { return c .c . Parent }
55
57
56
58
// loadChannels loads all the channels for the passed in org
57
59
func loadChannels (ctx context.Context , db sqlx.Queryer , orgID OrgID ) ([]assets.Channel , error ) {
58
- rows , err := db .Query (selectChannelsSQL , orgID )
60
+ rows , err := db .Queryx (selectChannelsSQL , orgID )
59
61
if err != nil {
60
62
return nil , errors .Annotatef (err , "error querying channels for org: %d" , orgID )
61
63
}
@@ -64,22 +66,9 @@ func loadChannels(ctx context.Context, db sqlx.Queryer, orgID OrgID) ([]assets.C
64
66
channels := make ([]assets.Channel , 0 , 2 )
65
67
for rows .Next () {
66
68
channel := & Channel {}
67
- var roles []string
68
- var parentName , parentUUID * string
69
-
70
- err := rows .Scan (& channel .id , & channel .uuid , & parentUUID , & parentName , & channel .name , & channel .country , & channel .address , pq .Array (& channel .schemes ), pq .Array (& roles ))
69
+ err := readJSONRow (rows , & channel .c )
71
70
if err != nil {
72
- return nil , errors .Annotate (err , "error scanning channel row" )
73
- }
74
-
75
- // populate our roles
76
- for _ , r := range roles {
77
- channel .roles = append (channel .roles , assets .ChannelRole (r ))
78
- }
79
-
80
- // and our parent if present
81
- if parentUUID != nil && parentName != nil {
82
- channel .parent = assets .NewChannelReference (assets .ChannelUUID (* parentUUID ), * parentName )
71
+ return nil , errors .Annotatef (err , "error unmarshalling channel" )
83
72
}
84
73
85
74
channels = append (channels , channel )
@@ -89,15 +78,14 @@ func loadChannels(ctx context.Context, db sqlx.Queryer, orgID OrgID) ([]assets.C
89
78
}
90
79
91
80
const selectChannelsSQL = `
92
- SELECT
93
- id,
94
- uuid,
95
- (SELECT uuid FROM channels_channel where id = parent_id) as parent_uuid,
96
- (SELECT name FROM channels_channel where id = parent_id) as parent_name,
97
- name,
98
- country,
99
- address,
100
- schemes,
81
+ SELECT ROW_TO_JSON(r) FROM (SELECT
82
+ c.id as id,
83
+ c.uuid uuid,
84
+ (SELECT ROW_TO_JSON(p) FROM (SELECT uuid, name FROM channels_channel cc where cc.id = c.parent_id) p) as parent,
85
+ c.name as name,
86
+ c.country as country,
87
+ c.address as address,
88
+ c.schemes as schemes,
101
89
(SELECT ARRAY(
102
90
SELECT CASE r
103
91
WHEN 'R' THEN 'receive'
@@ -106,13 +94,15 @@ SELECT
106
94
WHEN 'A' THEN 'answer'
107
95
WHEN 'U' THEN 'ussd'
108
96
END
109
- FROM unnest(regexp_split_to_array(role,'')) as r)
110
- ) as roles
97
+ FROM unnest(regexp_split_to_array(c.role,'')) as r)
98
+ ) as roles,
99
+ JSON_EXTRACT_PATH(c.config::json, 'matching_prefixes') as match_prefixes
111
100
FROM
112
- channels_channel
101
+ channels_channel c
113
102
WHERE
114
- org_id = $1 AND
115
- is_active = TRUE
103
+ c. org_id = $1 AND
104
+ c. is_active = TRUE
116
105
ORDER BY
117
- created_on ASC
106
+ c.created_on ASC
107
+ ) r;
118
108
`
0 commit comments