All Projects → samchon → safe-typeorm

samchon / safe-typeorm

Licence: other
TypeORM helper library enhancing safety in the compilation level

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to safe-typeorm

nest-serve
使用 Nestjs 8.x 以微服务方式开发的基础管理后台服务,并搭配 React 开发的管理后台前端(可自行根据 swagger 的接口开发对应的管理后台前端)
Stars: ✭ 97 (-39.37%)
Mutual labels:  typeorm
compiler
My first attempt to create a compiler
Stars: ✭ 16 (-90%)
Mutual labels:  compilation
nest-admin
NestJs CRUD for RESTful API使用 nestjs + mysql + typeorm + redis + jwt + swagger 企业中后台管理系统项目RBAC权限管理(细粒度到按钮)、实现单点登录等。
Stars: ✭ 165 (+3.13%)
Mutual labels:  typeorm
Micro
🏎Fast diffing and type safe SwiftUI style data source for UICollectionView
Stars: ✭ 77 (-51.87%)
Mutual labels:  safe
db-safedelete
Attempts to invoke force delete, if it fails - falls back to soft delete
Stars: ✭ 16 (-90%)
Mutual labels:  safe
make
The Ultimate Makefile to compile all your C, C++, Assembly and Fortran projects
Stars: ✭ 41 (-74.37%)
Mutual labels:  compilation
car-assembly
基于Vue3.0+WebGL+Nestjs搭建的汽车组装演示系统
Stars: ✭ 44 (-72.5%)
Mutual labels:  typeorm
nestjs-rest-cqrs-example
Example for Nest.js, MySQL, Redis, REST api, CQRS, DDD
Stars: ✭ 263 (+64.38%)
Mutual labels:  typeorm
node-typescript-starter
REST API using Node with typescript, KOA framework. TypeORM for SQL. Middlewares JWT (auth), CORS, Winston Logger, Error, Response
Stars: ✭ 19 (-88.12%)
Mutual labels:  typeorm
GoBarber
💈 Aplicação de agendamento para serviços de beleza, entre provedores e clientes.
Stars: ✭ 84 (-47.5%)
Mutual labels:  typeorm
safe-rules
详细的C/C++编程规范指南,由360质量工程部编著,适用于桌面、服务端及嵌入式软件系统。
Stars: ✭ 425 (+165.63%)
Mutual labels:  safe
BUA-FE
本科毕设,搭建一套小而全面的校园外卖系统。主要使用wei-xin-mini + TypeScript + nest.js + typeORM + rabbitmq技术栈。
Stars: ✭ 20 (-87.5%)
Mutual labels:  typeorm
tails
CLI for generating TypeGraphQL + TypeORM backend code
Stars: ✭ 22 (-86.25%)
Mutual labels:  typeorm
SAFE.Simplified
A lightweight alternative template of SAFE for happy cross-IDE full-stack F# development
Stars: ✭ 97 (-39.37%)
Mutual labels:  safe
nest-admin
采用nestjs typeorm vue开发的一套权限管理系统
Stars: ✭ 256 (+60%)
Mutual labels:  typeorm
mapet
Muitas pessoas tem bichinhos de estimação, entre eles os mais comuns são gatos e cachorros. Com a correria do dia a dia pode acontecer deles acabarem escapando, e ai aonde divulgar para ajudarem a encontrá-lo o mais rápido possível? Redes Sociais? WhatsApp? Pensando nisso criamos o mapet, um mapa que você indica aonde seu pet foi visto pela últi…
Stars: ✭ 15 (-90.62%)
Mutual labels:  typeorm
Project15-C-Client-Based-Formula-Editor
🍴 수식 셰프 🍴 - 수식편집을 도와주는 브라우저 확장프로그램
Stars: ✭ 43 (-73.12%)
Mutual labels:  typeorm
renestql
React, NestJS & GraphQL monorepo boilerplate managed with nx
Stars: ✭ 25 (-84.37%)
Mutual labels:  typeorm
SafeObject
IOS崩溃异常的处理,防止数组越界,字典空值处理
Stars: ✭ 84 (-47.5%)
Mutual labels:  safe
typescript-orm-benchmark
⚖️ ORM benchmarking for Node.js applications written in TypeScript
Stars: ✭ 106 (-33.75%)
Mutual labels:  typeorm

Safe-TypeORM

logo

GitHub license npm version Downloads Build Status FOSSA Status Chat on Gitter

npm install --save safe-typeorm

The safe-typeorm is a helper library for typeorm, enhancing safety in the compilation level.

  • When writing SQL query,
    • Errors would be detected in the compilation level
    • Auto Completion would be provided
    • Type Hint would be supported
  • You can implement App-join very conveniently
  • When SELECTing for JSON conversion
    • App-Join with the related entities would be automatically done
    • Exact JSON type would be automatically deduced
    • The performance would be automatically tuned
  • When INSERTing records
    • Sequence of tables would be automatically sorted by analyzing dependencies
    • The performance would be automatically tuned

Demonstration

ORM Model Classes

Entity Relationship Diagram

For demonstration, I've taken ORM model classes from the Test Automation Program of this safe-typeorm. The ORM model classes in the Test Automation Program represents a BBS (built-in bullet system) and its ERD (Entity Relationship Diagram) is like upper image.

Also, below is the list of ORM model classes used in the Test Automation Program. If you want to see the detailed code of the ORM model classes, click the below link. Traveling the ORM model classes, you would understand how to define the ORM model classes and their relationships through this safe-typeorm.

Safe Query Builder

Safe Query Builder

In safe-typeorm, you can write SQL query much safely and conveniently.

If you take a mistake when writing an SQL query, the error would be occured in the compilation level. Therefore, you don't need to suffer by runtime error by mistaken SQL query. Also, if you're writing wrong SQL query, the IDE (like VSCode) will warn you with the red underlined emphasizing, to tell you there can be an SQL error.

Also, safe-typeorm supports type hinting with auto-completion when you're writing the SQL query. Therefore, you can write SQL query much faster than before. Of course, the fast-written SQL query would be ensured its safety by the compiler and IDE.

export async function test_safe_query_builder(): Promise<void>
{
    const group: BbsGroup = await BbsGroup.findOneOrFail();
    const category: BbsCategory = await BbsCategory.findOneOrFail();

    const stmt: orm.SelectQueryBuilder<BbsQuestionArticle> = safe
        .createJoinQueryBuilder(BbsQuestionArticle, question =>
        {
            question.innerJoin("base", article =>
            {
                article.innerJoin("group");
                article.innerJoin("category");
                article.innerJoin("__mv_last").innerJoin("content");
            });
            question.leftJoin("answer")
                .leftJoin("base", "AA")
                .leftJoin("__mv_last", "AL")
                .leftJoin("content", "AC");
        })
        .andWhere(...BbsArticle.getWhereArguments("group", group))
        .andWhere(...BbsCategory.getWhereArguments("code", "!=", category.code))
        .select([
            BbsArticle.getColumn("id"),
            BbsGroup.getColumn("name", "group"),
            BbsCategory.getColumn("name", "category"),
            BbsArticle.getColumn("writer"),
            BbsArticleContent.getColumn("title"),
            BbsArticle.getColumn("created_at"),
            BbsArticleContent.getColumn("created_at", "updated_at"),

            BbsArticle.getColumn("AA.writer", "answer_writer"),
            BbsArticleContent.getColumn("AA.title", "answer_title"),
            BbsArticle.getColumn("AA.created_at", "answer_created_at"),
        ]);
    stmt;
}

App Join Builder

Safe Query Builder

With the AppJoinBuilder class, you can implement application level joining very easily.

Also, grammer of the AppJoinBuilder is exactly same with the JoinQueryBuilder. Therefore, you can swap JoinQueryBuilder and AppJoinBuilder very simply without any cost. Thus, you can just select one of them suitable for your case.

export async function test_app_join_builder(): Promise<void>
{
    const builder: safe.AppJoinBuilder<BbsReviewArticle> = safe
        .createAppJoinBuilder(BbsReviewArticle, review =>
        {
            review.join("base", article =>
            {
                article.join("group");
                article.join("category");
                article.join("contents", content =>
                {
                    content.join("reviewContent");
                    content.join("files");
                });
                article.join("comments").join("files");
            });
        });
}

Furthermore, you've determined to using only the AppJoinBuilder, you can configure it much safely. With the AppJoinBuilder.initialize() method, you've configure all of the relationship accessors, and it prevents any type of ommission by your mistake.

export async function test_app_join_builder_initialize(): Promise<void>
{
    const builder = safe.AppJoinBuilder.initialize(BbsGroup, {
        articles: safe.AppJoinBuilder.initialize(BbsArticle, {
            group: undefined,
            review: safe.AppJoinBuilder.initialize(BbsReviewArticle, {
                base: undefined,
            }),
            category: safe.AppJoinBuilder.initialize(BbsCategory, {
                articles: undefined,
                children: undefined,
                parent: "recursive"
            }),
            contents: safe.AppJoinBuilder.initialize(BbsArticleContent, {
                article: undefined,
                files: "join"
            }),
            comments: safe.AppJoinBuilder.initialize(BbsComment, {
                article: undefined,
                files: "join"
            }),
            tags: "join",
            __mv_last: undefined,
            question: undefined,
            answer: undefined,
        })
    });
}

JSON Select Builder

Class Diagram

In safe-typeorm, when you want to load DB records and convert them to a JSON data, you don't need to write any SELECT or JOIN query. You also do not need to consider any performance tuning. Just write down the ORM -> JSON conversion plan, then safe-typeorm will do everything.

The JsonSelectBuilder is the class doing everything. It will analyze your JSON conversion plan, and compose the JSON conversion method automatically with the exact JSON type what you want. Furthermore, the JsonSelectBuilder finds the best (applicataion level) joining plan by itself, when being constructed.

Below code is an example converting ORM model class instances to JSON data with the JsonSelectBuilder. As you can see, there's no special script in the below code, but only the conversion plan is. As I've mentioned, JsonSelectBuilder will construct the exact JSON type by analyzing your conversion plan. Also, the performance tuning would be done automatically.

Therefore, just enjoy the JsonSelectBuilder without any worry.

export async function test_json_select_builder(models: BbsGroup[]): Promise<void>
{
    const builder = BbsGroup.createJsonSelectBuilder
    ({
        articles: BbsArticle.createJsonSelectBuilder
        ({
            group: safe.DEFAULT, // ID ONLY
            category: BbsCategory.createJsonSelectBuilder
            ({ 
                parent: "recursive" as const, // RECURSIVE JOIN
            }),
            tags: BbsArticleTag.createJsonSelectBuilder
            (
                {}, 
                tag => tag.value // OUTPUT CONVERSION BY MAPPING
            ),
            contents: BbsArticleContent.createJsonSelectBuilder
            ({
                files: "join" as const
            }),
        })
    });

    // GET JSON DATA FROM THE BUILDER
    const raw = await builder.getMany(models);

    // THE RETURN TYPE IS ALWAYS EXACT
    // THEREFORE, TYPEOF "RAW" AND "I-BBS-GROUP" ARE EXACTLY SAME
    const regular: IBbsGroup[] = raw;
    const inverse: typeof raw = regular;
}

Insert Collection

When you want to execute INSERT query for lots of records of plural tables, you've to consider dependency relationships. Also, you may construct extended SQL query manually by yourself, if you're interested in the performance tuning.

However, with the InsertCollection class provided by this safe-typeorm, you don't need to consider any dependcy relationship. You also do not need to consider any performance tuning. The InsertCollection will analyze the dependency relationships and orders the insertion sequence automatically. Also, the InsertCollection utilizes the extended insertion query for the optimizing performance.

import safe from "safe-typeorm";
import std from "tstl";

export async function archive
    (
        comments: BbsComment[],
        questions: BbsQuestionArticle[],
        reviews: BbsArticleReview[],
        groups: BbsGroup[],
        files: AttachmentFile[],
        answers: BbsAnswerArticle[],
        categories: BbsCategory[],
        comments: BbsComment[],
        articles: BbsArticle[],
        contents: BbsArticleContent[],
        tags: BbsArticleTag[],
    ): Promise<void>
{
    // PREPARE A NEW COLLECTION
    const collection: safe.InsertCollection = new safe.InsertCollection();
    
    // PUSH TABLE RECORDS TO THE COLLECTION WITH RANDOM SHULFFLING
    const massive = [
        comments,
        questions,
        reviews,
        groups,
        files,
        answers,
        comments,
        articles,
        contents,
        tags
    ];
    std.ranges.shuffle(massive);
    for (const records of massive)
        collection.push(records);

    // PUSH INDIVIDUAL RECORDS
    for (const category of categories)
        collection.push(category);
    
    // EXECUTE THE INSERT QUERY
    await collection.execute();
}

Appendix

TypeORM

typeorm#8184

I've awaited next version of the typeorm for many years, and I can't wait no more.

So I've decided to implement the next version by myself. I'd wanted to contribute to this typeorm after the next version implementation has been completed, but it was not possible by critical change on the relationship definition like Has.OneToMany or Belongs.ManyToOne. Therefore, I've published the next version as a helper library of thetypeorm.

I dedicate this safe-typeorm to the typeorm. If developers of the typeorm accept the critical change on the relationship definition, it would be the next version of the typeorm. Otherwise they reject, this safe-typeorm would be left as a helper library like now.

Nestia

https://github.com/samchon/nestia

nestia is another library what I've developed, automatic SDK generator for the NestJS backend server. With those safe-typeorm and nestia, you can reduce lots of costs and time for developing the backend server.

When you're developing a backend server using the NestJS, you don't need any extra dedication, for delivering the Rest API to the client developers, like writing the swagger comments. You just run the nestia up, then nestia would generate the SDK automatically, by analyzing your controller classes in the compliation and runtime level.

With the automatically generated SDK through the nestia, client developer also does not need any extra work, like reading swagger and writing the duplicated interaction code. Client developer only needs to import the SDK and calls matched function with the await symbol.

import api from "@samchon/bbs-api";
import { IBbsArticle } from "@samchon/bbs-api/lib/structures/bbs/IBbsArticle";
import { IPage } from "@samchon/bbs-api/lib/structures/common/IPage";

export async function test_article_read(connection: api.IConnection): Promise<void>
{
    // LIST UP ARTICLE SUMMARIES
    const index: IPage<IBbsArticle.ISummary> = await api.functional.bbs.articles.index
    (
        connection,
        "free",
        { limit: 100, page: 1 }
    );

    // READ AN ARTICLE DETAILY
    const article: IBbsArticle = await api.functional.bbs.articles.at
    (
        connection,
        "free",
        index.data[0].id
    );
    console.log(article.title, aritlce.body, article.files);
}

Archidraw

https://www.archisketch.com/

I have special thanks to the Archidraw, where I'm working for.

The Archidraw is a great IT company developing 3D interior editor and lots of solutions based on the 3D assets. Also, the Archidraw is the first company who had adopted safe-typeorm on their commercial backend project, even safe-typeorm was in the alpha level.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].