react-native-flipper-databases
Version:
Flipper Databases plugin for React Native
116 lines (99 loc) • 3.31 kB
text/typescript
import type Realm from 'realm';
import type {
DatabaseDescriptor,
DatabaseDriver,
DatabaseExecuteSQLResponse,
DatabaseGetTableDataResponse,
DatabaseGetTableInfoResponse,
DatabaseGetTableStructureResponse,
} from '../types';
export class RealmDriver implements DatabaseDriver {
constructor(private readonly name: string, private readonly realm: Realm) {}
async getDatabases(): Promise<DatabaseDescriptor[]> {
return [
{
name: this.name,
},
];
}
async getTableNames(_databaseDescriptor: DatabaseDescriptor): Promise<string[]> {
// Return all models excluding embedded ones
return this.realm.schema.filter(schema => !schema.embedded).map(schema => schema.name);
}
async getTableStructure(
_databaseDescriptor: DatabaseDescriptor,
schema: string
): Promise<DatabaseGetTableStructureResponse> {
const schemaProps = getSchemaProperties(this.realm, schema);
const schemaColumns = Object.keys(schemaProps);
const columnsDef = schemaColumns.map(k => [
k,
schemaProps[k].type,
schemaProps[k].default,
schemaProps[k].indexed,
schemaProps[k].optional,
schemaProps[k].mapTo,
]);
return {
structureColumns: ['name', 'type', 'defaultValue', 'isIndexed', 'isOptional', 'mapTo'],
structureValues: columnsDef,
indexesColumns: ['name', 'type'],
indexesValues: schemaColumns
.filter(k => schemaProps[k].indexed)
.map(k => [k, schemaProps[k].type]),
};
}
async getTableData(
_databaseDescriptor: DatabaseDescriptor,
schema: string,
order: string | undefined,
reverse: boolean,
start: number,
count: number
): Promise<DatabaseGetTableDataResponse> {
const schemaProperties = getSchemaProperties(this.realm, schema);
const allColumns = Object.keys(schemaProperties);
const dataSnapshot = this.realm.objects(schema).snapshot();
const sorted = order ? dataSnapshot.sorted(order, reverse) : dataSnapshot;
const data = sorted.slice(start, start + count);
return {
columns: allColumns,
values: data.map(row => {
const rowJSON = row.toJSON();
return allColumns.map(colName => getCellValue(rowJSON, colName));
}),
start,
count: data.length,
total: dataSnapshot.length,
};
}
async getTableInfo(
_databaseDescriptor: DatabaseDescriptor,
table: string
): Promise<DatabaseGetTableInfoResponse> {
const tableSchema = this.realm.schema.find(schema => schema.name === table);
return {
definition: JSON.stringify(tableSchema, null, 2),
};
}
async executeSql(
_databaseDescriptor: DatabaseDescriptor,
_query: string
): Promise<DatabaseExecuteSQLResponse> {
return Promise.reject('Unsupported method');
}
}
// UTILITY FUNCTIONS
function getSchemaProperties(
realm: Realm,
schemaName: string
): Record<string, Realm.ObjectSchemaProperty> {
return (realm.schema.find(schema => schema.name === schemaName)?.properties ?? {}) as Record<
string,
Realm.ObjectSchemaProperty
>;
}
export function getCellValue(row: Record<string, unknown>, columnName: string): unknown {
const cellValue = row[columnName];
return typeof cellValue === 'object' ? JSON.stringify(cellValue, null, 2) : cellValue;
}