Fossil SCM

Refactor and simplify forum_statuses().

stephan 2026-05-26 21:08 UTC forum-statuses
Commit d9b2025741fd8286f41df667bc4958da9c4b08d5b0f28049324f809d9bef22a3
1 file changed +20 -41
+20 -41
--- src/forum.c
+++ src/forum.c
@@ -88,11 +88,10 @@
8888
*/
8989
static const ForumStatusList * forum_statuses(void){
9090
static ForumStatusList fses = {0,0};
9191
static int once = 0;
9292
while( !once ){
93
- Stmt q;
9493
++once;
9594
/* Read `forum-statuses` setting and transform it into the
9695
** fses object.
9796
**
9897
** Maybe: if it's empty, synthesize a length-1 list from
@@ -99,61 +98,41 @@
9998
** {value:"default",label:"Default",...}. It's expected that
10099
** usage may be slightly simplified if we always have a non-empty
101100
** list. A length-1 list is, for purposes of the UI, identical to
102101
** an empty one - status selection/filtering makes no sense if
103102
** there's only one choice. */
104
- db_get("forum-statuses", 0);
105103
db_multi_exec(
106104
"CREATE TEMP TABLE forumstatus("
107
- " ord, label, value, descr"
105
+ " ord INTEGER PRIMARY KEY AUTOINCREMENT,"
106
+ " label, value, descr"
108107
");"
109
- );
110
- db_prepare(&q,
111
- "WITH setting(v) AS ("
112
- " SELECT value v FROM config WHERE name='forum-statuses'"
113
- "),"
114
- "room(r) AS ("
115
- " SELECT e.value FROM setting s, jsonb_each(s.v) e"
116
- " WHERE json_valid(s.v, 0x02)"
117
- ")"
118
- " SELECT r->>'label', r->>'value', r->>'description'"
119
- " FROM room"
120
- );
121
- /*
122
- ** Quirk: we run the query twice: once to count and once to insert
123
- ** into the forumstatus table. We could do the query and populate
124
- ** in the same step but we need an ordinal value to go with each
125
- ** so that we can retain their order. If the above CTE can be
126
- ** altered to provide a sequential ordinal value then we can
127
- ** eliminate this double-step.
128
- */
129
- while( SQLITE_ROW==db_step(&q) ){
130
- ++fses.n;
131
- }
108
+ "INSERT INTO forumstatus(label,value,descr)"
109
+ " WITH setting(v) AS ("
110
+ " SELECT value v FROM config WHERE name='forum-statuses'"
111
+ " ),"
112
+ " room(r) AS ("
113
+ " SELECT e.value FROM setting s, jsonb_each(s.v) e"
114
+ " WHERE json_valid(s.v, 0x02)"
115
+ " )"
116
+ " SELECT r->>'label', r->>'value', r->>'description'"
117
+ " FROM room"
118
+ );
119
+ fses.n = (unsigned)db_int(0, "SELECT count(*) FROM forumstatus");
132120
if( fses.n ){
133121
int i = 0;
134
- Stmt qIns;
122
+ Stmt q;
123
+ db_prepare(&q,"SELECT label, value, descr FROM forumstatus"
124
+ " ORDER BY ord");
135125
fses.aStatus = fossil_malloc(sizeof(fses.aStatus[0]) * fses.n);
136
- db_reset(&q);
137
- db_prepare(&qIns,
138
- "INSERT INTO forumstatus(ord,label,value,descr)"
139
- " VALUES(:ord,:label,:value,:descr)");
140126
while( SQLITE_ROW==db_step(&q) ){
141127
ForumStatus * fs = &fses.aStatus[i++];
142128
fs->zLabel = fossil_strdup(db_column_text(&q, 0));
143129
fs->zValue = fossil_strdup(db_column_text(&q, 1));
144130
fs->zDescr = fossil_strdup(db_column_text(&q, 2));
145
- db_reset(&qIns);
146
- db_bind_int(&qIns, ":ord", i);
147
- db_bind_text(&qIns, ":label", fs->zLabel);
148
- db_bind_text(&qIns, ":value", fs->zValue);
149
- db_bind_text(&qIns, ":descr", fs->zDescr);
150
- db_step(&qIns);
151
- }
152
- db_finalize(&qIns);
153
- }
154
- db_finalize(&q);
131
+ }
132
+ db_finalize(&q);
133
+ }
155134
}
156135
return &fses;
157136
}
158137
159138
/*
160139
--- src/forum.c
+++ src/forum.c
@@ -88,11 +88,10 @@
88 */
89 static const ForumStatusList * forum_statuses(void){
90 static ForumStatusList fses = {0,0};
91 static int once = 0;
92 while( !once ){
93 Stmt q;
94 ++once;
95 /* Read `forum-statuses` setting and transform it into the
96 ** fses object.
97 **
98 ** Maybe: if it's empty, synthesize a length-1 list from
@@ -99,61 +98,41 @@
99 ** {value:"default",label:"Default",...}. It's expected that
100 ** usage may be slightly simplified if we always have a non-empty
101 ** list. A length-1 list is, for purposes of the UI, identical to
102 ** an empty one - status selection/filtering makes no sense if
103 ** there's only one choice. */
104 db_get("forum-statuses", 0);
105 db_multi_exec(
106 "CREATE TEMP TABLE forumstatus("
107 " ord, label, value, descr"
 
108 ");"
109 );
110 db_prepare(&q,
111 "WITH setting(v) AS ("
112 " SELECT value v FROM config WHERE name='forum-statuses'"
113 "),"
114 "room(r) AS ("
115 " SELECT e.value FROM setting s, jsonb_each(s.v) e"
116 " WHERE json_valid(s.v, 0x02)"
117 ")"
118 " SELECT r->>'label', r->>'value', r->>'description'"
119 " FROM room"
120 );
121 /*
122 ** Quirk: we run the query twice: once to count and once to insert
123 ** into the forumstatus table. We could do the query and populate
124 ** in the same step but we need an ordinal value to go with each
125 ** so that we can retain their order. If the above CTE can be
126 ** altered to provide a sequential ordinal value then we can
127 ** eliminate this double-step.
128 */
129 while( SQLITE_ROW==db_step(&q) ){
130 ++fses.n;
131 }
132 if( fses.n ){
133 int i = 0;
134 Stmt qIns;
 
 
135 fses.aStatus = fossil_malloc(sizeof(fses.aStatus[0]) * fses.n);
136 db_reset(&q);
137 db_prepare(&qIns,
138 "INSERT INTO forumstatus(ord,label,value,descr)"
139 " VALUES(:ord,:label,:value,:descr)");
140 while( SQLITE_ROW==db_step(&q) ){
141 ForumStatus * fs = &fses.aStatus[i++];
142 fs->zLabel = fossil_strdup(db_column_text(&q, 0));
143 fs->zValue = fossil_strdup(db_column_text(&q, 1));
144 fs->zDescr = fossil_strdup(db_column_text(&q, 2));
145 db_reset(&qIns);
146 db_bind_int(&qIns, ":ord", i);
147 db_bind_text(&qIns, ":label", fs->zLabel);
148 db_bind_text(&qIns, ":value", fs->zValue);
149 db_bind_text(&qIns, ":descr", fs->zDescr);
150 db_step(&qIns);
151 }
152 db_finalize(&qIns);
153 }
154 db_finalize(&q);
155 }
156 return &fses;
157 }
158
159 /*
160
--- src/forum.c
+++ src/forum.c
@@ -88,11 +88,10 @@
88 */
89 static const ForumStatusList * forum_statuses(void){
90 static ForumStatusList fses = {0,0};
91 static int once = 0;
92 while( !once ){
 
93 ++once;
94 /* Read `forum-statuses` setting and transform it into the
95 ** fses object.
96 **
97 ** Maybe: if it's empty, synthesize a length-1 list from
@@ -99,61 +98,41 @@
98 ** {value:"default",label:"Default",...}. It's expected that
99 ** usage may be slightly simplified if we always have a non-empty
100 ** list. A length-1 list is, for purposes of the UI, identical to
101 ** an empty one - status selection/filtering makes no sense if
102 ** there's only one choice. */
 
103 db_multi_exec(
104 "CREATE TEMP TABLE forumstatus("
105 " ord INTEGER PRIMARY KEY AUTOINCREMENT,"
106 " label, value, descr"
107 ");"
108 "INSERT INTO forumstatus(label,value,descr)"
109 " WITH setting(v) AS ("
110 " SELECT value v FROM config WHERE name='forum-statuses'"
111 " ),"
112 " room(r) AS ("
113 " SELECT e.value FROM setting s, jsonb_each(s.v) e"
114 " WHERE json_valid(s.v, 0x02)"
115 " )"
116 " SELECT r->>'label', r->>'value', r->>'description'"
117 " FROM room"
118 );
119 fses.n = (unsigned)db_int(0, "SELECT count(*) FROM forumstatus");
 
 
 
 
 
 
 
 
 
 
 
120 if( fses.n ){
121 int i = 0;
122 Stmt q;
123 db_prepare(&q,"SELECT label, value, descr FROM forumstatus"
124 " ORDER BY ord");
125 fses.aStatus = fossil_malloc(sizeof(fses.aStatus[0]) * fses.n);
 
 
 
 
126 while( SQLITE_ROW==db_step(&q) ){
127 ForumStatus * fs = &fses.aStatus[i++];
128 fs->zLabel = fossil_strdup(db_column_text(&q, 0));
129 fs->zValue = fossil_strdup(db_column_text(&q, 1));
130 fs->zDescr = fossil_strdup(db_column_text(&q, 2));
131 }
132 db_finalize(&q);
133 }
 
 
 
 
 
 
 
134 }
135 return &fses;
136 }
137
138 /*
139

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button