Skip to content

Commit 06687eb

Browse files
authored
Minor changes to storage api (#196)
* Change listModules to take a regex pattern (as a string) so it can easily be passed to a server for server-side stroage. In names.ts, replaced makeModulePathPrefix with makeModulePathRegexPattern. In project.ts: Updated renameOrCopyProject, deleteProject, and downloadProject to pass regex string instead of filter callback to listModules. Modified renameOrCopyModule to call fetchModuleContentText instead of listModules. * Changed downloadProject to take a Project instead of a projectName (string).
1 parent fa92a90 commit 06687eb

File tree

5 files changed

+32
-24
lines changed

5 files changed

+32
-24
lines changed

src/reactComponents/Menu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ export function Component(props: MenuProps): React.JSX.Element {
336336
}
337337

338338
try {
339-
const blobUrl = await storageProject.downloadProject(props.storage, props.project.projectName);
339+
const blobUrl = await storageProject.downloadProject(props.storage, props.project);
340340
const filename = props.project.projectName + storageNames.UPLOAD_DOWNLOAD_FILE_EXTENSION;
341341

342342
// Create a temporary link to download the file

src/storage/client_side_storage.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,12 @@ class ClientSideStorage implements commonStorage.Storage {
126126
}
127127

128128
async listModules(
129-
opt_modulePathFilter?: commonStorage.ModulePathFilter):
130-
Promise<{[path: string]: storageModuleContent.ModuleContent}> {
129+
opt_modulePathRegexPattern?: string
130+
): Promise<{[path: string]: storageModuleContent.ModuleContent}> {
131+
132+
const regExp = opt_modulePathRegexPattern
133+
? new RegExp(opt_modulePathRegexPattern)
134+
: null;
131135
return new Promise((resolve, reject) => {
132136
const pathToModuleContent: {[path: string]: storageModuleContent.ModuleContent} = {};
133137
const openCursorRequest = this.db.transaction([MODULES_STORE_NAME], 'readonly')
@@ -144,7 +148,7 @@ class ClientSideStorage implements commonStorage.Storage {
144148
const value = cursor.value;
145149
// TODO(lizlooney): do we need value.path? Is there another way to get the path?
146150
const modulePath = value.path;
147-
if (!opt_modulePathFilter || opt_modulePathFilter(modulePath)) {
151+
if (!regExp || regExp.test(modulePath)) {
148152
const moduleContent = storageModuleContent.parseModuleContentText(value.content);
149153
pathToModuleContent[modulePath] = moduleContent;
150154
}

src/storage/common_storage.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,20 @@
2121

2222
import * as storageModuleContent from './module_content';
2323

24-
export type ModulePathFilter = (modulePath: string) => boolean;
25-
2624
export interface Storage {
2725
saveEntry(entryKey: string, entryValue: string): Promise<void>;
26+
2827
fetchEntry(entryKey: string, defaultValue: string): Promise<string>;
29-
listModules(opt_modulePathFilter?: ModulePathFilter): Promise<{[path: string]: storageModuleContent.ModuleContent}>;
28+
29+
listModules(
30+
opt_modulePathRegexPattern?: string
31+
): Promise<{[path: string]: storageModuleContent.ModuleContent}>;
32+
3033
fetchModuleDateModifiedMillis(modulePath: string): Promise<number>;
34+
3135
fetchModuleContentText(modulePath: string): Promise<string>;
36+
3237
saveModule(modulePath: string, moduleContentText: string): Promise<void>;
38+
3339
deleteModule(modulePath: string): Promise<void>;
3440
}

src/storage/names.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,16 @@ export function snakeCaseToPascalCase(snakeCaseName: string): string {
7676
}
7777

7878
/**
79-
* Returns the module path prefix for the given project name.
79+
* Returns the module path regex pattern for modules in the given project.
8080
*/
81-
export function makeModulePathPrefix(projectName: string): string {
82-
return projectName + '/';
81+
export function makeModulePathRegexPattern(projectName: string): string {
82+
const prefix = projectName + '/';
83+
const suffix = JSON_FILE_EXTENSION;
84+
return '^' + escapeRegExp(prefix) + '.*' + escapeRegExp(suffix) + '$';
85+
}
86+
87+
function escapeRegExp(text: string): string {
88+
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
8389
}
8490

8591
/**

src/storage/project.ts

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,8 @@ export async function copyProject(
159159
async function renameOrCopyProject(
160160
storage: commonStorage.Storage, project: Project, newProjectName: string,
161161
rename: boolean): Promise<void> {
162-
const modulePathPrefix = storageNames.makeModulePathPrefix(project.projectName);
163162
const pathToModuleContent = await storage.listModules(
164-
(modulePath: string) => modulePath.startsWith(modulePathPrefix));
163+
storageNames.makeModulePathRegexPattern(project.projectName));
165164

166165
for (const modulePath in pathToModuleContent) {
167166
const className = storageNames.getClassName(modulePath);
@@ -182,9 +181,9 @@ async function renameOrCopyProject(
182181
*/
183182
export async function deleteProject(
184183
storage: commonStorage.Storage, project: Project): Promise<void> {
185-
const modulePathPrefix = storageNames.makeModulePathPrefix(project.projectName);
186184
const pathToModuleContent = await storage.listModules(
187-
(modulePath: string) => modulePath.startsWith(modulePathPrefix));
185+
storageNames.makeModulePathRegexPattern(project.projectName));
186+
188187
for (const modulePath in pathToModuleContent) {
189188
await storage.deleteModule(modulePath);
190189
}
@@ -286,14 +285,8 @@ export async function copyModuleInProject(
286285
async function renameOrCopyModule(
287286
storage: commonStorage.Storage, project: Project, newClassName: string,
288287
oldModule: storageModule.Module, rename: boolean): Promise<string> {
289-
const pathToModuleContent = await storage.listModules(
290-
(modulePath: string) => modulePath === oldModule.modulePath);
291-
if (! (oldModule.modulePath in pathToModuleContent)) {
292-
throw new Error('Failed to find module with path ' + oldModule.modulePath);
293-
}
294-
295288
const newModulePath = storageNames.makeModulePath(project.projectName, newClassName);
296-
const moduleContentText = pathToModuleContent[oldModule.modulePath].getModuleContentText();
289+
const moduleContentText = await storage.fetchModuleContentText(oldModule.modulePath);
297290
await storage.saveModule(newModulePath, moduleContentText);
298291
if (rename) {
299292
// For rename, delete the old module.
@@ -403,10 +396,9 @@ export function findModuleByModulePath(project: Project, modulePath: string): st
403396
* Produce the blob for downloading a project.
404397
*/
405398
export async function downloadProject(
406-
storage: commonStorage.Storage, projectName: string): Promise<string> {
407-
const modulePathPrefix = storageNames.makeModulePathPrefix(projectName);
399+
storage: commonStorage.Storage, project: Project): Promise<string> {
408400
const pathToModuleContent = await storage.listModules(
409-
(modulePath: string) => modulePath.startsWith(modulePathPrefix));
401+
storageNames.makeModulePathRegexPattern(project.projectName));
410402

411403
const classNameToModuleContentText: {[className: string]: string} = {}; // value is module content text
412404
for (const modulePath in pathToModuleContent) {

0 commit comments

Comments
 (0)