Skip to content

Commit 1139536

Browse files
committed
Keep SQLite storage metadata out of site sync
Exclude the managed database directory and renames into or out of it from filesystem sync. Database changes already use SQL sync; copying another site's discovery file or locks can break its local storage. Related: WordPress/sqlite-database-integration#502
1 parent 49fceff commit 1139536

6 files changed

Lines changed: 62 additions & 27 deletions

File tree

‎packages/php-wasm/fs-journal/src/lib/fs-journal.ts‎

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { PHP, UniversalPHP } from '@php-wasm/universal';
22
import { __private__dont__use } from '@php-wasm/universal';
3-
import { Semaphore, basename, joinPaths } from '@php-wasm/util';
3+
import { Semaphore, basename, isParentOf, joinPaths } from '@php-wasm/util';
44
import { logger } from '@php-wasm/logger';
55

66
export type EmscriptenFS = any;
@@ -108,28 +108,51 @@ export type FilesystemOperation =
108108
| DeleteOperation
109109
| RenameOperation;
110110

111+
export type FSJournalOptions = {
112+
excludePaths?: string[];
113+
excludeNames?: string[];
114+
};
115+
111116
export function journalFSEvents(
112117
php: PHP,
113118
fsRoot: string,
114-
onEntry: (entry: FilesystemOperation) => void = () => {}
119+
onEntry: (entry: FilesystemOperation) => void = () => {},
120+
{ excludePaths = [], excludeNames = [] }: FSJournalOptions = {}
115121
) {
122+
const shouldRecord = (path: string) =>
123+
isParentOf(fsRoot, path) &&
124+
!excludePaths.some((excluded) => isParentOf(excluded, path)) &&
125+
(!excludeNames.length || !excludeNames.includes(basename(path)));
126+
116127
function bindToCurrentRuntime() {
117128
fsRoot = normalizePath(fsRoot);
118129
const FS = php[__private__dont__use].FS;
119130
const FSHooks = createFSHooks(FS, (entry: FilesystemOperation) => {
120-
// Only journal entries inside the specified root directory.
121-
if (entry.path.startsWith(fsRoot)) {
131+
const recordSource = shouldRecord(entry.path);
132+
if (entry.operation !== 'RENAME') {
133+
if (recordSource) {
134+
onEntry(entry);
135+
}
136+
return;
137+
}
138+
const recordDestination = shouldRecord(entry.toPath);
139+
if (recordSource && recordDestination) {
122140
onEntry(entry);
123-
} else if (
124-
entry.operation === 'RENAME' &&
125-
entry.toPath.startsWith(fsRoot)
126-
) {
141+
} else if (recordSource) {
142+
onEntry({
143+
operation: 'DELETE',
144+
path: entry.path,
145+
nodeType: entry.nodeType,
146+
});
147+
} else if (recordDestination) {
127148
for (const op of recordExistingPath(
128149
php,
129150
entry.path,
130151
entry.toPath
131152
)) {
132-
onEntry(op);
153+
if (shouldRecord(op.path)) {
154+
onEntry(op);
155+
}
133156
}
134157
}
135158
});

‎packages/php-wasm/fs-journal/src/lib/index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ export {
44
hydrateUpdateFileOps,
55
normalizeFilesystemOperations,
66
} from './fs-journal';
7-
export type { FilesystemOperation } from './fs-journal';
7+
export type { FilesystemOperation, FSJournalOptions } from './fs-journal';

‎packages/playground/remote/src/lib/boot-playground-remote.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ export async function bootPlaygroundRemote() {
145145
async cli(argv, options) {
146146
return await phpWorkerApi.cli(argv, options);
147147
},
148-
async journalFSEvents(root: string, callback) {
149-
return phpWorkerApi.journalFSEvents(root, callback);
148+
async journalFSEvents(root: string, callback, options) {
149+
return phpWorkerApi.journalFSEvents(root, callback, options);
150150
},
151151
async replayFSJournal(events: FilesystemOperation[]) {
152152
return phpWorkerApi.replayFSJournal(events);

‎packages/playground/remote/src/lib/playground-worker-endpoint.ts‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import type { FilesystemOperation } from '@php-wasm/fs-journal';
1+
import type {
2+
FilesystemOperation,
3+
FSJournalOptions,
4+
} from '@php-wasm/fs-journal';
25
import { journalFSEvents, replayFSJournal } from '@php-wasm/fs-journal';
36
import type { EmscriptenDownloadMonitor } from '@php-wasm/progress';
47
import { setURLScope } from '@php-wasm/scopes';
@@ -575,9 +578,15 @@ export abstract class PlaygroundWorkerEndpoint extends PHPWorker {
575578

576579
async journalFSEvents(
577580
root: string,
578-
callback: (op: FilesystemOperation) => void
581+
callback: (op: FilesystemOperation) => void,
582+
options?: FSJournalOptions
579583
) {
580-
return journalFSEvents(this.__internal_getPHP()!, root, callback);
584+
return journalFSEvents(
585+
this.__internal_getPHP()!,
586+
root,
587+
callback,
588+
options
589+
);
581590
}
582591

583592
async replayFSJournal(events: FilesystemOperation[]) {

‎packages/playground/sync/src/fs.ts‎

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
import type { FilesystemOperation } from '@php-wasm/fs-journal';
22
import type { PlaygroundClient } from '@wp-playground/client';
3+
import { joinPaths } from '@php-wasm/util';
34

45
export async function journalFSOperations(
56
playground: PlaygroundClient,
67
onEntry: (op: FilesystemOperation) => void
78
) {
8-
await playground.journalFSEvents(
9-
'/wordpress/wp-content',
10-
async (entry: FilesystemOperation) => {
11-
if (
12-
entry.path.endsWith('/.ht.sqlite') ||
13-
entry.path.endsWith('/.ht.sqlite-journal')
14-
) {
15-
return;
16-
}
17-
onEntry(entry);
18-
}
9+
const wpContentPath = joinPaths(
10+
await playground.documentRoot,
11+
'wp-content'
1912
);
13+
// SQL is synchronized separately. Storage paths and locks belong to each site.
14+
await playground.journalFSEvents(wpContentPath, onEntry, {
15+
excludePaths: [joinPaths(wpContentPath, 'database')],
16+
excludeNames: [
17+
'.ht.sqlite',
18+
'.ht.sqlite-journal',
19+
'.ht.sqlite-wal',
20+
'.ht.sqlite-shm',
21+
],
22+
});
2023
}

‎packages/playground/sync/src/setup-playground-sync.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export async function setupPlaygroundSync(
4242
journalSQLQueries(playground, (query: SQLJournalEntry) => {
4343
localChanges.sql.push(query);
4444
});
45-
journalFSOperations(playground, (op: FilesystemOperation) => {
45+
await journalFSOperations(playground, (op: FilesystemOperation) => {
4646
localChanges.fs.push(op);
4747
});
4848

0 commit comments

Comments
 (0)