Fossil SCM
Refactor and simplify forum_statuses().
Commit
d9b2025741fd8286f41df667bc4958da9c4b08d5b0f28049324f809d9bef22a3
Parent
74b8376dad3423d…
1 file changed
+20
-41
+20
-41
| --- src/forum.c | ||
| +++ src/forum.c | ||
| @@ -88,11 +88,10 @@ | ||
| 88 | 88 | */ |
| 89 | 89 | static const ForumStatusList * forum_statuses(void){ |
| 90 | 90 | static ForumStatusList fses = {0,0}; |
| 91 | 91 | static int once = 0; |
| 92 | 92 | while( !once ){ |
| 93 | - Stmt q; | |
| 94 | 93 | ++once; |
| 95 | 94 | /* Read `forum-statuses` setting and transform it into the |
| 96 | 95 | ** fses object. |
| 97 | 96 | ** |
| 98 | 97 | ** Maybe: if it's empty, synthesize a length-1 list from |
| @@ -99,61 +98,41 @@ | ||
| 99 | 98 | ** {value:"default",label:"Default",...}. It's expected that |
| 100 | 99 | ** usage may be slightly simplified if we always have a non-empty |
| 101 | 100 | ** list. A length-1 list is, for purposes of the UI, identical to |
| 102 | 101 | ** an empty one - status selection/filtering makes no sense if |
| 103 | 102 | ** there's only one choice. */ |
| 104 | - db_get("forum-statuses", 0); | |
| 105 | 103 | db_multi_exec( |
| 106 | 104 | "CREATE TEMP TABLE forumstatus(" |
| 107 | - " ord, label, value, descr" | |
| 105 | + " ord INTEGER PRIMARY KEY AUTOINCREMENT," | |
| 106 | + " label, value, descr" | |
| 108 | 107 | ");" |
| 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"); | |
| 132 | 120 | if( fses.n ){ |
| 133 | 121 | int i = 0; |
| 134 | - Stmt qIns; | |
| 122 | + Stmt q; | |
| 123 | + db_prepare(&q,"SELECT label, value, descr FROM forumstatus" | |
| 124 | + " ORDER BY ord"); | |
| 135 | 125 | 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 | 126 | while( SQLITE_ROW==db_step(&q) ){ |
| 141 | 127 | ForumStatus * fs = &fses.aStatus[i++]; |
| 142 | 128 | fs->zLabel = fossil_strdup(db_column_text(&q, 0)); |
| 143 | 129 | fs->zValue = fossil_strdup(db_column_text(&q, 1)); |
| 144 | 130 | 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 | + } | |
| 155 | 134 | } |
| 156 | 135 | return &fses; |
| 157 | 136 | } |
| 158 | 137 | |
| 159 | 138 | /* |
| 160 | 139 |
| --- 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 |