Socket
Book a DemoInstallSign in
Socket

typeorm-sharding-repository

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

typeorm-sharding-repository

TypeORM Sharding Repository: Enables TypeORM to be utilized in a distributed database environment.

latest
Source
npmnpm
Version
0.3.1
Version published
Maintainers
1
Created
Source

TypeORM Sharding Repository

  • Enables TypeORM to be utilized in a distributed database environment.

Node.js CI NPM Version License

Install

  • NPM
$ npm install typeorm-sharding-repository --save
  • Yarn
$ yarn add typeorm-sharding-repository

Usage

1. Prepare DataSources.

  • Instead of setting the TypeORM datasource, set the ShardingManager. Most of the settings are similar to TypeORM.
  • In this example, the User entity has a key of number type. It is recommended to set the ShardingManager according to the rules of a compatible key or range of keys.
const dbConf = {
    host: 'localhost',
    database: 'playground',
    username: 'postgres',
    password: 'postgrespw',
    synchronize: true,
    logging: 'all',
};

const shardManager = await ShardingManager.init({
    shardingType: ShardingType.RANGE,
    // The settings here apply to all database shards. 
    type: 'postgres',
    entities: [User],
    shards: [
        // Settings for each database.
        // minKey and maxKey can also use various types. For multi-columns, a tuple format is also possible.
        // onInitialize(typeorm.DataSource) callback is optional.
        { ...dbConf, port: 55000, minKey: 0, maxKey: 1000, onInitialize: (dataSource) => {/* What to do after data source initialization */} },
        { ...dbConf, port: 55001, minKey: 1000, maxKey: 2000, onInitialize: (dataSource) => {/**/} },
        { ...dbConf, port: 55002, minKey: 2000, maxKey: 3000, onInitialize: (dataSource) => {/**/} },
    ],
});

2. Apply to Entity

  • Use @ShardingEntity instead of @Entity decorator.
  • Inherit ShardingBaseEntity instead of BaseEntity.
  • New data will be inserted into the added database shard.
@ShardingEntity<User, number>({
    // Modular sharding will be supported in the future.
    type: ShardingType.RANGE,
    
    // Decide in which shard the entity will be processed. To process one entity, it can be called as many as the number of shards.
    // If data is being inserted, the key may be empty.
    // If false is returned in all cases, the last shard is chosen.
    // For minKey and maxKey, the values defined in ShardingManager are delivered.
    // If you do not want to manage multiple ShardingManagers, you can adjust the minKey and maxKey keys according to the 1:n relationship of entities in this function.
    findShard: (entity: User, minKey, maxKey) => entity.id && minKey <= entity.id && entity.id < maxKey,
    
    // Similar to findShard, but an ID value is passed instead of an entity.
    // The type of ID is ambiguous. In this example, passed as number.
    // Usually, ID values referenced in repository.findByIds() etc. are passed.
    // You need to determine which shard the id resides on.
    findShardById: (id: number, minKey, maxKey) => id && minKey <= id && id < maxKey,
})
export class User extends ShardingBaseEntity {
    @PrimaryGeneratedColumn() id: number;
    @Column() firstName: string;
    @Column() lastName: string;
    @Column() age: number;
}

3. RepositoryService (Abstract repository for TypeORM.BaseEntity and ShardingBaseEntity)

  • RepositoryService compatible with TypeORM.BaseEntity and ShardingBaseEntity.
  • With this pattern, changing whether or not sharding is applied does not change the code.
  • Repository Interface
// Both repository services have the same interface. 
const typeormRepository = RepositoryService.of(MyEntityBasedOnTypeormBaseEntity);
const shardingRepository = RepositoryService.of(MyEntityBasedOnShardingBaseEntity);

interface AbstractRepositoryService<Entity> {
    create(entityLike: DeepPartial<Entity>): Entity | Entity[];
    create(entityLike: DeepPartial<Entity>): Entity | Entity[];
    create(entityLike?: DeepPartial<Entity> | DeepPartial<Entity>[]): Entity | Entity[];

    save(entities: DeepPartial<Entity>[], options?: SaveOptions): Promise<Entity[]>;
    save(entity: DeepPartial<Entity>, options?: SaveOptions): Promise<Entity>;

    remove(entities: Entity[], options?: RemoveOptions): Promise<Entity[]>;
    remove(entity: Entity, options?: RemoveOptions): Promise<Entity>;

    softRemove(entities: Entity[], options?: SaveOptions): Promise<Entity[]>;
    softRemove(entity: Entity, options?: SaveOptions): Promise<Entity>;

    update(
        criteria: string | string[] | number | number[] | Date | Date[] | ObjectID | ObjectID[] | FindOptionsWhere<Entity>,
        partialEntity: QueryDeepPartialEntity<Entity>
    ): Promise<UpdateResult>;

    delete(
        criteria: string | string[] | number | number[] | Date | Date[] | ObjectID | ObjectID[] | FindOptionsWhere<Entity>
    ): Promise<DeleteResult>;

    count(options?: FindManyOptions<Entity>): Promise<number>;
    countBy(where: FindOptionsWhere<Entity>): Promise<number>;

    find(options?: FindManyOptions<Entity>): Promise<Entity[]>;
    findBy(where: FindOptionsWhere<Entity>): Promise<Entity[]>;

    findAndCount(options?: FindManyOptions<Entity>): Promise<[Entity[], number]>;
    findAndCountBy(where: FindOptionsWhere<Entity>): Promise<[Entity[], number]>;

    findOne(options: FindOneOptions<Entity>): Promise<Entity | null | undefined>;
    findOneBy(where: FindOptionsWhere<Entity>): Promise<Entity | null | undefined>;
    findOneById(id: string | number | Date | ObjectID): Promise<Entity | null>;
    findByIds(ids: any[]): Promise<Entity[]>;
}

4. Entity [static] method

// Provides almost the same functionality as BaseEntity.
const entity = await Case1.save({
    firstName: 'Typeorm',
    lastName: 'Sharding',
    age: 10,
});

await entity.save();
await entity.remove();
await entity.softRemove();
await entity.recover();
await entity.reload();


//      _______.___________.    ___   .___________. __    ______ 
//     /       |           |   /   \  |           ||  |  /      |
//    |   (----`---|  |----`  /  ^  \ `---|  |----`|  | |  ,----'
//     \   \       |  |      /  /_\  \    |  |     |  | |  |     
// .----)   |      |  |     /  _____  \   |  |     |  | |  `----.
// |_______/       |__|    /__/     \__\  |__|     |__|  \______|

// Create entity instance
Case1.create();
Case1.create({firstName: 'Typeorm', ...});

// Returns all entities from all shards. Sort order is not guaranteed.
await Case1.find();

// Returns all entities where the value of "firstName" column is 'Typeorm' from all shards. Sort order is not guaranteed.
await Case1.find({ where: {firstName: 'Typeorm'} });

// Fetch one entity where the value of "firstName" column is 'Typeorm' from all shards.
// If an entity is found on multiple shards, the entity from the oldest shard is returned.
await Case1.findOneBy({ firstName: 'Typeorm' });

// Fetch one entity by ID from single shard.
await Case1.findOneById(1);

// Count entities where the value of "firstName" column is 'Typeorm' from all shards.
await Case1.count({ where: {firstName: 'Typeorm'} });

// Update multiple entities.
await Case1.update({ firstName: 'Typeorm' }, { lastName: 'Bob' });

// Remove entity from single shard.
await Case1.remove(entity);


//  __        ______   ____    __    ____     __       ___________    ____  _______  __      
// |  |      /  __  \  \   \  /  \  /   /    |  |     |   ____\   \  /   / |   ____||  |     
// |  |     |  |  |  |  \   \/    \/   /     |  |     |  |__   \   \/   /  |  |__   |  |     
// |  |     |  |  |  |   \            /      |  |     |   __|   \      /   |   __|  |  |     
// |  `----.|  `--'  |    \    /\    /       |  `----.|  |____   \    /    |  |____ |  `----.
// |_______| \______/      \__/  \__/        |_______||_______|   \__/     |_______||_______|

// Returns all TypeORM DataSources
Case1.getAllDataSource();

// Returns TypeORM DataSource for specific entity
Case1.getDataSource(entity);

// Returns TypeORM DataSource for specific ID value
Case1.getDataSourceById(ID_VALUE);

// Returns all TypeORM Reposigories
Case1.getAllRepository<Case1>();

// Returns TypeORM Reposigory for specific entity
Case1.getRepository<Case1>(entity);

// Returns TypeORM Manager for specific entity
Case1.getManager<Case1>(entity);

Contributors

Keywords

TypeORM

FAQs

Package last updated on 16 Oct 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.