@@ -101,7 +101,7 @@ WHERE p.deleted = true
101101 AND p.users IS NULL
102102ORDER BY
103103 p.project_id, s.string_id
104- LIMIT 10000
104+ LIMIT 1000
105105` ;
106106
107107const Q_CLEANUP_PROJECTS = `
@@ -130,12 +130,18 @@ export async function cleanup_old_projects_data(
130130) {
131131 const settings = await getServerSettings ( ) ;
132132 const on_prem = settings . kucalc === KUCALC_ON_PREMISES ;
133+ const delete_data = settings . delete_project_data ;
133134 const L0 = log . extend ( "cleanup_old_projects_data" ) ;
134135 const L = L0 . debug ;
135136
136- L ( "args" , { max_run_m, on_prem } ) ;
137- const start_ts = new Date ( ) ;
137+ L ( "args" , { max_run_m, on_prem, delete_data } ) ;
138138
139+ if ( ! delete_data ) {
140+ L ( `deleting project data is disabled ('delete_project_data' setting).` ) ;
141+ return ;
142+ }
143+
144+ const start_ts = new Date ( ) ;
139145 const pool = getPool ( ) ;
140146
141147 let numSyncStr = 0 ;
@@ -171,27 +177,34 @@ export async function cleanup_old_projects_data(
171177 numProj += 1 ;
172178 let delRows = 0 ;
173179
180+ // Clean up data *on* a given project. For now, remove all site licenses.
181+ await pool . query (
182+ `UPDATE projects SET site_license = NULL WHERE project_id = $1` ,
183+ [ project_id ] ,
184+ ) ;
185+
174186 if ( on_prem ) {
175187 L2 ( `delete all project files` ) ;
176188 await deleteProjectFiles ( L2 , project_id ) ;
177189
178190 L2 ( `deleting all shared files` ) ;
179- // this is something like /shared/projects/${project_id}
180- const shared_path = pathToFiles ( project_id , "" ) ;
181- await fs . rm ( shared_path , { recursive : true , force : true } ) ;
182-
183- // for now, on-prem only as well. This gets rid of all sorts of data in tables specific to the given project.
184- delRows += await delete_associated_project_data ( L2 , project_id ) ;
191+ try {
192+ // this is something like /shared/projects/${project_id}
193+ const shared_path = pathToFiles ( project_id , "" ) ;
194+ await fs . rm ( shared_path , { recursive : true , force : true } ) ;
195+ } catch ( err ) {
196+ L2 ( `Unable to delete shared files: ${ err } ` ) ;
197+ }
185198 }
186199
200+ // This gets rid of all sorts of data in tables specific to the given project.
201+ delRows += await delete_associated_project_data ( L2 , project_id ) ;
202+
187203 // now, that we're done with that project, mark it as state.state ->> 'deleted'
188- // in addition to the flag "deleted = true"
189- await callback2 ( db . set_project_state , {
190- project_id,
191- state : "deleted" ,
192- } ) ;
204+ // in addition to the flag "deleted = true". This also updates the state.time timestamp.
205+ await callback2 ( db . set_project_state , { project_id, state : "deleted" } ) ;
193206 L2 (
194- `finished deleting project data | deleted ${ delRows } entries | setting state.state="deleted"` ,
207+ `finished deleting project data | deleted ${ delRows } entries | state.state="deleted"` ,
195208 ) ;
196209 }
197210
@@ -247,7 +260,7 @@ async function delete_associated_project_data(
247260 const { rowsDeleted } = await bulkDelete ( {
248261 table : "listings" ,
249262 field : "project_id" ,
250- id : "project_id" , // TODO listings has a more complex ID, is this a problem?
263+ id : "project_id" , // TODO listings has a more complex ID, which means this gets rid of everything in one go. should be fine, though.
251264 value : project_id ,
252265 } ) ;
253266 total += rowsDeleted ;
0 commit comments