Check-in [7a29e882c9]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Corrected triggers to work for SQLite. Made project remarks per-user.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 7a29e882c9a9f693b84a2aab2816a38fd3a89fef
User & Date: MCO 2013-12-03 14:17:56.283
Context
2014-02-07
17:18
Added all remaining extra files. Removed extraneous files. check-in: 5aa08a7411 user: MCO tags: trunk
2013-12-03
14:17
Corrected triggers to work for SQLite. Made project remarks per-user. check-in: 7a29e882c9 user: MCO tags: trunk
12:57
Added SQL file with a proposal for a data structure to be used in a more comprehensive approach to project-timekeeping. check-in: 4d13bbac76 user: MCO tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to doc/Generic project data structure.sql.
1
2
3
4
5
6







7

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23


24
25
26
27
28
29
30
CREATE TABLE Project
( project_id            INTEGER PRIMARY KEY
, name                  TEXT    NOT NULL    COLLATE NOCASE  UNIQUE
, code                  TEXT                COLLATE NOCASE
, description           TEXT
, customer              TEXT                COLLATE NOCASE







, remarks               TEXT

);

CREATE TABLE ProjectPeople
( projectpeople_id      INTEGER PRIMARY KEY
, project_id            INTEGER NOT NULL    REFERENCES Project
, person                TEXT    NOT NULL    COLLATE NOCASE
, user_id               INTEGER             REFERENCES User
, role                  TEXT                COLLATE NOCASE  -- REFERENCES PeopleRole ON UPDATE CASCADE
, remarks               TEXT
, UNIQUE (project_id, person, role)
);

CREATE TABLE PeopleRole
( role                  TEXT    NOT NULL    PRIMARY KEY COLLATE NOCASE
, description           TEXT
);



CREATE TABLE User
( user_id               INTEGER PRIMARY KEY
, code                  TEXT    NOT NULL    COLLATE NOCASE
, full_name             TEXT    NOT NULL    COLLATE NOCASE
, remarks               TEXT
);






>
>
>
>
>
>
>
|
>
















>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
CREATE TABLE Project
( project_id            INTEGER PRIMARY KEY
, name                  TEXT    NOT NULL    COLLATE NOCASE  UNIQUE
, code                  TEXT                COLLATE NOCASE
, description           TEXT
, customer              TEXT                COLLATE NOCASE
);
INSERT INTO Project VALUES (1, '(pauze)', 'AFW', 'Lunch, of niet-werkgerelateerde zaken', NULL);

CREATE TABLE ProjectRemarks
( project_remark_id     INTEGER PRIMARY KEY
, project_id            INTEGER NOT NULL    REFERENCES Project
, user_id               INTEGER NOT NULL    REFERENCES User
, remarks               TEXT    NOT NULL
, UNIQUE (project_id, user_id)
);

CREATE TABLE ProjectPeople
( projectpeople_id      INTEGER PRIMARY KEY
, project_id            INTEGER NOT NULL    REFERENCES Project
, person                TEXT    NOT NULL    COLLATE NOCASE
, user_id               INTEGER             REFERENCES User
, role                  TEXT                COLLATE NOCASE  -- REFERENCES PeopleRole ON UPDATE CASCADE
, remarks               TEXT
, UNIQUE (project_id, person, role)
);

CREATE TABLE PeopleRole
( role                  TEXT    NOT NULL    PRIMARY KEY COLLATE NOCASE
, description           TEXT
);
INSERT INTO PeopleRole VALUES ('projectleider', NULL);
INSERT INTO PeopleRole VALUES ('contactpersoon', NULL);

CREATE TABLE User
( user_id               INTEGER PRIMARY KEY
, code                  TEXT    NOT NULL    COLLATE NOCASE
, full_name             TEXT    NOT NULL    COLLATE NOCASE
, remarks               TEXT
);
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
















129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151












152
153
154
155
156
157
158
159
*/
 
/*
To allow FTS searching for projects as well as activities, perhaps add an FTS table for each:
*/
CREATE VIEW vfts_Project AS
    SELECT p.project_id
    ,      p.name, p.code, p.description, p.remarks, p.customer
    ,      group_concat(pp.person || ' (' || pp.role || ')' || ifnull(': ' || pp.remarks, ''), '; ')
      FROM Project p
           LEFT JOIN ProjectPeople pp ON p.project_id = pp.project_id
  GROUP BY p.project_id
;

CREATE VIRTUAL TABLE fts_Project USING FTS4 ( name, code, description, remarks, customer, people, tokenize=unicode61);

-- automatically update the FTS table using a few triggers
CREATE TRIGGER trg_aiu_Project
AFTER INSERT OR UPDATE ON Project
BEGIN
    INSERT OR REPLACE INTO fts_Project ( docid, name, code, description, remarks, customer, people )
        SELECT *
          FROM vfts_Project
         WHERE project_id = NEW.project_id
    ;
END;
CREATE TRIGGER trg_aiu_ProjectPeople
















AFTER INSERT OR UPDATE ON ProjectPeople
BEGIN
    INSERT OR REPLACE INTO fts_Project ( docid, name, code, description, remarks, customer, people )
        SELECT *
          FROM vfts_Project
         WHERE project_id = NEW.project_id
    ;
END;
CREATE TRIGGER trg_au_User_Project
AFTER UPDATE OF code, full_name ON User
BEGIN
    INSERT OR REPLACE INTO fts_Project ( docid, name, code, description, remarks, customer, people )
        SELECT *
          FROM vfts_Project
         WHERE project_id IN (SELECT DISTINCT project_id FROM ProjectPeople WHERE user_id = NEW.user_id)
    ;
END;


CREATE VIRTUAL TABLE fts_Activity USING FTS4 ( remarks, username, tokenize=unicode61 );

-- automatically update the FTS table using a few triggers
CREATE TRIGGER trg_aiu_Activity












AFTER INSERT OR UPDATE OF remarks, user_id ON Activity
BEGIN
    INSERT OR REPLACE INTO fts_Activity ( docid, remarks, username )
        SELECT a.activity_id
        ,      a.remarks
        ,      u.code || ifnull(' (' || u.full_name || ')', '')
          FROM Activity a
               LEFT JOIN User u ON a.user_id = u.user_id







|






|


|
|

|


|
<

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

|


|
<




|










|
>
>
>
>
>
>
>
>
>
>
>
>
|







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
*/
 
/*
To allow FTS searching for projects as well as activities, perhaps add an FTS table for each:
*/
CREATE VIEW vfts_Project AS
    SELECT p.project_id
    ,      p.name, p.code, p.description, p.customer
    ,      group_concat(pp.person || ' (' || pp.role || ')' || ifnull(': ' || pp.remarks, ''), '; ')
      FROM Project p
           LEFT JOIN ProjectPeople pp ON p.project_id = pp.project_id
  GROUP BY p.project_id
;

CREATE VIRTUAL TABLE fts_Project USING FTS4 ( name, code, description, customer, people, tokenize=unicode61);

-- automatically update the FTS table using a few triggers
CREATE TRIGGER trg_ai_Project
AFTER INSERT ON Project
BEGIN
    INSERT OR REPLACE INTO fts_Project ( docid, name, code, description, customer, people )
        SELECT *
          FROM vfts_Project
         WHERE project_id = NEW.project_id;

END;
CREATE TRIGGER trg_au_Project
AFTER UPDATE ON Project
BEGIN
    INSERT OR REPLACE INTO fts_Project ( docid, name, code, description, customer, people )
        SELECT *
          FROM vfts_Project
         WHERE project_id = NEW.project_id;
END;
CREATE TRIGGER trg_ai_ProjectPeople
AFTER INSERT ON ProjectPeople
BEGIN
    INSERT OR REPLACE INTO fts_Project ( docid, name, code, description, customer, people )
        SELECT *
          FROM vfts_Project
         WHERE project_id = NEW.project_id;
END;
CREATE TRIGGER trg_au_ProjectPeople
AFTER UPDATE ON ProjectPeople
BEGIN
    INSERT OR REPLACE INTO fts_Project ( docid, name, code, description, customer, people )
        SELECT *
          FROM vfts_Project
         WHERE project_id = NEW.project_id;

END;
CREATE TRIGGER trg_au_User_Project
AFTER UPDATE OF code, full_name ON User
BEGIN
    INSERT OR REPLACE INTO fts_Project ( docid, name, code, description, customer, people )
        SELECT *
          FROM vfts_Project
         WHERE project_id IN (SELECT DISTINCT project_id FROM ProjectPeople WHERE user_id = NEW.user_id)
    ;
END;


CREATE VIRTUAL TABLE fts_Activity USING FTS4 ( remarks, username, tokenize=unicode61 );

-- automatically update the FTS table using a few triggers
CREATE TRIGGER trg_ai_Activity
AFTER INSERT ON Activity
BEGIN
    INSERT OR REPLACE INTO fts_Activity ( docid, remarks, username )
        SELECT a.activity_id
        ,      a.remarks
        ,      u.code || ifnull(' (' || u.full_name || ')', '')
          FROM Activity a
               LEFT JOIN User u ON a.user_id = u.user_id
         WHERE a.activity_id = NEW.activity_id
    ;
END;
CREATE TRIGGER trg_au_Activity
AFTER UPDATE OF remarks, user_id ON Activity
BEGIN
    INSERT OR REPLACE INTO fts_Activity ( docid, remarks, username )
        SELECT a.activity_id
        ,      a.remarks
        ,      u.code || ifnull(' (' || u.full_name || ')', '')
          FROM Activity a
               LEFT JOIN User u ON a.user_id = u.user_id
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197


198
         WHERE a.user_id = NEW.user_id
    ;
END;


-- Query to perform the actual search:
SELECT p.project_id

,      p.name
,      snippet
,      datetime(a.start_time, 'localtime') AS time_start
,      datetime(a.start_time, 'localtime', '+' || a.duration || ' seconds') AS time_finish
  FROM (
    SELECT docid AS project_id
    ,      NULL AS activity_id
    ,      snippet(fts_Project) AS snippet
      FROM fts_Project
     WHERE fts_Project MATCH :SearchTerms
    UNION
    SELECT NULL AS project_id
    ,      docid AS activity_id
    ,      snippet(fts_Activity) AS snippet
      FROM fts_Activity
     WHERE fts_Activity MATCH :SearchTerms
       ) m
       LEFT JOIN Activity a ON m.activity_id = a.activity_id
       LEFT JOIN Project p ON coalesce(m.project_id, a.project_id) = p.project_id


;







>



















>
>

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
         WHERE a.user_id = NEW.user_id
    ;
END;


-- Query to perform the actual search:
SELECT p.project_id
,      a.activity_id
,      p.name
,      snippet
,      datetime(a.start_time, 'localtime') AS time_start
,      datetime(a.start_time, 'localtime', '+' || a.duration || ' seconds') AS time_finish
  FROM (
    SELECT docid AS project_id
    ,      NULL AS activity_id
    ,      snippet(fts_Project) AS snippet
      FROM fts_Project
     WHERE fts_Project MATCH :SearchTerms
    UNION
    SELECT NULL AS project_id
    ,      docid AS activity_id
    ,      snippet(fts_Activity) AS snippet
      FROM fts_Activity
     WHERE fts_Activity MATCH :SearchTerms
       ) m
       LEFT JOIN Activity a ON m.activity_id = a.activity_id
       LEFT JOIN Project p ON coalesce(m.project_id, a.project_id) = p.project_id
ORDER BY time_start DESC
,        time_finish DESC
;