Skip to content

Commit

Permalink
chore(fs): align storage implementations (#4724)
Browse files Browse the repository at this point in the history
Co-authored-by: Sergey Petushkov <[email protected]>
  • Loading branch information
mabaasit and gribnoysup authored Aug 31, 2023
1 parent 580f4c8 commit 2c91060
Show file tree
Hide file tree
Showing 38 changed files with 1,148 additions and 382 deletions.
257 changes: 248 additions & 9 deletions package-lock.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import path from 'path';
import { getStoragePaths } from '@mongodb-js/compass-utils';
import { getAppName, getStoragePath } from '@mongodb-js/compass-utils';

export function getUserDataFolderPath() {
const { appName, basepath } = getStoragePaths() || {};
const appName = getAppName();
const basepath = getStoragePath();
if (appName === undefined || basepath === undefined) {
throw new Error('cannot access user data folder path');
}
// Todo: https://jira.mongodb.org/browse/COMPASS-7080
// We should directly call getStoragePaths wherever this function is called.
// It creates nested folder with appName as folder name.
return path.join(basepath, appName);
}
4 changes: 2 additions & 2 deletions packages/compass-preferences-model/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
"reformat": "npm run prettier -- --write . && npm run eslint . --fix"
},
"dependencies": {
"@mongodb-js/compass-user-data": "^0.1.0",
"@mongodb-js/compass-logging": "^1.1.8",
"@mongodb-js/compass-utils": "^0.3.4",
"ampersand-collection-filterable": "^0.3.0",
"ampersand-rest-collection": "^6.0.0",
"ampersand-state": "5.0.3",
Expand All @@ -56,7 +56,7 @@
"zod": "^3.22.2"
},
"devDependencies": {
"@mongodb-js/compass-utils": "^0.3.4",
"@mongodb-js/compass-user-data": "^0.1.0",
"@mongodb-js/eslint-config-compass": "^1.0.8",
"@mongodb-js/mocha-config-compass": "^1.3.0",
"@testing-library/react": "^12.1.4",
Expand Down
3 changes: 1 addition & 2 deletions packages/compass-preferences-model/src/setup-preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import type {
} from './preferences';
import type { ParsedGlobalPreferencesResult } from './global-config';

import { getStoragePaths } from '@mongodb-js/compass-utils';
import type { PreferencesAccess } from '.';

let preferencesSingleton: Preferences | undefined;
Expand All @@ -22,7 +21,7 @@ export async function setupPreferences(
}

const preferences = (preferencesSingleton = new Preferences(
getStoragePaths()?.basepath,
undefined,
globalPreferences,
process.env.COMPASS_TEST_USE_PREFERENCES_SANDBOX === 'true'
));
Expand Down
74 changes: 28 additions & 46 deletions packages/compass-preferences-model/src/storage.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { UUID } from 'bson';
import { promises as fs } from 'fs';
import { join } from 'path';
import type { UserPreferences } from './preferences';
import { UserData } from '@mongodb-js/compass-user-data';

export abstract class BasePreferencesStorage {
abstract setup(): Promise<void>;
Expand Down Expand Up @@ -34,44 +33,35 @@ export class SandboxPreferences extends BasePreferencesStorage {
}

export class StoragePreferences extends BasePreferencesStorage {
private readonly folder = 'AppPreferences';
private readonly file = 'General.json';
private readonly defaultPreferences: UserPreferences;
private readonly userData: UserData<UserPreferences>;

constructor(private preferences: UserPreferences, private basepath?: string) {
constructor(private preferences: UserPreferences, private basePath?: string) {
super();
this.defaultPreferences = preferences;
}

private getFolderPath() {
return join(this.basepath ?? '', this.folder);
}

private getFilePath() {
return join(this.getFolderPath(), this.file);
this.userData = new UserData({
subdir: 'AppPreferences',
basePath,
});
}

async setup() {
// Ensure folder exists
await fs.mkdir(this.getFolderPath(), { recursive: true });

try {
this.preferences = await this.readPreferences();
} catch (e) {
if ((e as any).code !== 'ENOENT') {
throw e;
}
// Create the file for the first time
await fs.writeFile(
this.getFilePath(),
JSON.stringify(this.defaultPreferences, null, 2),
'utf-8'
);
await this.userData.write(this.file, this.defaultPreferences);
}
}

private async readPreferences(): Promise<UserPreferences> {
return JSON.parse(await fs.readFile(this.getFilePath(), 'utf8'));
private async readPreferences() {
return await this.userData.readOne(this.file, {
ignoreErrors: false,
});
}

getPreferences() {
Expand All @@ -86,11 +76,7 @@ export class StoragePreferences extends BasePreferencesStorage {
...(await this.readPreferences()),
...attributes,
};
await fs.writeFile(
this.getFilePath(),
JSON.stringify(newPreferences, null, 2),
'utf-8'
);
await this.userData.write(this.file, newPreferences);

this.preferences = newPreferences;
}
Expand All @@ -103,21 +89,15 @@ export type User = {
};

export class UserStorage {
private readonly folder = 'Users';
constructor(private readonly basepath: string = '') {}

private getFolderPath() {
return join(this.basepath, this.folder);
}

private getFilePath(id: string) {
return join(this.getFolderPath(), `${id}.json`);
private readonly userData: UserData<User>;
constructor(basePath?: string) {
this.userData = new UserData({
subdir: 'Users',
basePath,
});
}

async getOrCreate(id: string): Promise<User> {
// Ensure folder exists
await fs.mkdir(this.getFolderPath(), { recursive: true });

if (!id) {
return this.createUser();
}
Expand All @@ -128,12 +108,14 @@ export class UserStorage {
if ((e as any).code !== 'ENOENT') {
throw e;
}
return this.createUser();
return await this.createUser();
}
}

async getUser(id: string): Promise<User> {
const user = JSON.parse(await fs.readFile(this.getFilePath(id), 'utf-8'));
const user = await this.userData.readOne(this.getFileName(id), {
ignoreErrors: false,
});
return {
id: user.id,
createdAt: new Date(user.createdAt),
Expand Down Expand Up @@ -161,11 +143,11 @@ export class UserStorage {
}

private async writeUser(user: User): Promise<User> {
await fs.writeFile(
this.getFilePath(user.id),
JSON.stringify(user, null, 2),
'utf-8'
);
await this.userData.write(this.getFileName(user.id), user);
return this.getUser(user.id);
}

private getFileName(id: string) {
return `${id}.json`;
}
}
5 changes: 2 additions & 3 deletions packages/compass-preferences-model/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ import preferences, { preferencesAccess } from '.';
import type { ParsedGlobalPreferencesResult } from '.';
import { setupPreferences } from './setup-preferences';
import { UserStorage } from './storage';
import { getStoragePaths } from '@mongodb-js/compass-utils';

export async function setupPreferencesAndUser(
globalPreferences: ParsedGlobalPreferencesResult
): Promise<void> {
await setupPreferences(globalPreferences);
const userStorage = new UserStorage(getStoragePaths()?.basepath);
const userStorage = new UserStorage();
const user = await userStorage.getOrCreate(getActiveUserId());
// update user id (telemetryAnonymousId) in preferences if new user was created.
await preferences.savePreferences({ telemetryAnonymousId: user.id });
Expand All @@ -23,7 +22,7 @@ function getActiveUserId() {
}

export async function getActiveUser() {
const userStorage = new UserStorage(getStoragePaths()?.basepath);
const userStorage = new UserStorage();
return userStorage.getUser(getActiveUserId());
}

Expand Down
10 changes: 5 additions & 5 deletions packages/compass-query-bar/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@
"@mongodb-js/compass-components": "^1.12.0",
"@mongodb-js/compass-editor": "^0.11.0",
"@mongodb-js/compass-logging": "^1.1.8",
"@mongodb-js/compass-utils": "^0.3.4",
"@mongodb-js/compass-user-data": "^0.1.0",
"@mongodb-js/mongodb-constants": "^0.6.0",
"bson": "^5.3.0",
"mongodb-query-util": "^2.0.2",
"compass-preferences-model": "^2.12.0",
"mongodb-query-util": "^2.0.2",
"react": "^17.0.2"
},
"devDependencies": {
Expand Down Expand Up @@ -99,12 +99,12 @@
"dependencies": {
"@mongodb-js/atlas-service": "^0.3.0",
"@mongodb-js/compass-components": "^1.12.0",
"mongodb-query-util": "^2.0.2",
"@mongodb-js/compass-editor": "^0.11.0",
"@mongodb-js/compass-logging": "^1.1.8",
"@mongodb-js/compass-utils": "^0.3.4",
"@mongodb-js/compass-user-data": "^0.1.0",
"@mongodb-js/mongodb-constants": "^0.6.0",
"bson": "^5.3.0",
"compass-preferences-model": "^2.12.0"
"compass-preferences-model": "^2.12.0",
"mongodb-query-util": "^2.0.2"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ const FAVORITE_QUERY = {
...BASE_QUERY,
};

function createStore(basepath?: string) {
const favoriteQueryStorage = new FavoriteQueryStorage(basepath);
const recentQueryStorage = new RecentQueryStorage(basepath);
function createStore(basepath: string) {
const favoriteQueryStorage = new FavoriteQueryStorage({ basepath });
const recentQueryStorage = new RecentQueryStorage({ basepath });

const store = configureStore({
namespace: 'airbnb.listings',
Expand All @@ -65,7 +65,7 @@ function createStore(basepath?: string) {
};
}

const renderQueryHistory = (basepath?: string) => {
const renderQueryHistory = (basepath: string) => {
const data = createStore(basepath);
render(
<Provider store={data.store}>
Expand All @@ -87,15 +87,15 @@ describe('query-history', function () {

context('zero state', function () {
it('in recents', function () {
renderQueryHistory();
renderQueryHistory(tmpDir);
userEvent.click(screen.getByText(/recents/i));
expect(
screen.getByText(/your recent queries will appear here\./i)
).to.exist;
});

it('in favorites', function () {
renderQueryHistory();
renderQueryHistory(tmpDir);
userEvent.click(screen.getByText(/favorites/i));
expect(
screen.getByText(/your favorite queries will appear here\./i)
Expand All @@ -105,7 +105,7 @@ describe('query-history', function () {

context('renders list of queries', function () {
it('recent', async function () {
const { store, recentQueryStorage } = renderQueryHistory();
const { store, recentQueryStorage } = renderQueryHistory(tmpDir);
Sinon.stub(recentQueryStorage, 'loadAll').returns(
Promise.resolve([RECENT_QUERY] as any)
);
Expand All @@ -122,7 +122,7 @@ describe('query-history', function () {
});

it('favorite', async function () {
const { store, favoriteQueryStorage } = renderQueryHistory();
const { store, favoriteQueryStorage } = renderQueryHistory(tmpDir);
Sinon.stub(favoriteQueryStorage, 'loadAll').returns(
Promise.resolve([FAVORITE_QUERY] as any)
);
Expand All @@ -142,7 +142,7 @@ describe('query-history', function () {

context('deletes a query', function () {
it('recent', async function () {
const { store, recentQueryStorage } = renderQueryHistory();
const { store, recentQueryStorage } = renderQueryHistory(tmpDir);
Sinon.stub(recentQueryStorage, 'loadAll').returns(
Promise.resolve([RECENT_QUERY] as any)
);
Expand All @@ -164,7 +164,7 @@ describe('query-history', function () {
});

it('favorite', async function () {
const { store, favoriteQueryStorage } = renderQueryHistory();
const { store, favoriteQueryStorage } = renderQueryHistory(tmpDir);
Sinon.stub(favoriteQueryStorage, 'loadAll').returns(
Promise.resolve([FAVORITE_QUERY] as any)
);
Expand Down
11 changes: 2 additions & 9 deletions packages/compass-query-bar/src/stores/query-bar-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {
RecentQueryStorage,
getQueryAttributes,
} from '../utils';
import { getStoragePaths } from '@mongodb-js/compass-utils';
import { AtlasService } from '@mongodb-js/atlas-service/renderer';

// Partial of DataService that mms shares with Compass.
Expand Down Expand Up @@ -80,14 +79,8 @@ export function configureStore(options: Partial<QueryBarStoreOptions> = {}) {
namespace,
dataProvider,
atlasService = new AtlasService(),
recentQueryStorage = new RecentQueryStorage(
options.basepath ?? getStoragePaths()?.basepath,
namespace
),
favoriteQueryStorage = new FavoriteQueryStorage(
options.basepath ?? getStoragePaths()?.basepath,
namespace
),
recentQueryStorage = new RecentQueryStorage({ namespace }),
favoriteQueryStorage = new FavoriteQueryStorage({ namespace }),
} = options;

const store = _createStore(
Expand Down
Loading

0 comments on commit 2c91060

Please sign in to comment.