[컴] 맥의 filesystem 은 case insensitive 이다.

 

APFS / case sensitive / 대소문자 구분 / 구별 / 대소문자 구별안한다 / 맥 파일시스템 / 맥에서 대소문자 / 파일명 / 폴더명

맥의 filesystem 은 case insensitive 이다.

평소 맥을 잘 안써서 몰랐는데, 누군가 맥도 윈도우즈(windows)처럼 대소문자 구분을 안한다고 해서 찾아봤다.

그래서 보니, 맥은 filesystem 을 만들때 옵션으로 case sensitive(대소문자 구별) 를 선택적으로 할 수 있게 해놨다.

ref. 1, ref. 2 에서 확인할 수 있다. APFS 는 기본적으로 case insensitive 인데, case-sensitive 가 지원되는 APFS 를 사용할 수도 있다.

References

  1. big sur - What is the default partition type (case sensitive or insensitive) in Macbook pro 2020 (BigSur)? - Ask Different
  2. File system formats available in Disk Utility on Mac - Apple Support

[컴] vendure plugin 만들기 - plugin 적용

vendure extension / vendure plugin /db migration

vendure plugin 만들기 - plugin 적용

여기서는 만들어진 plugin 을 추가하고, 적용하는 방법을 다룬다.

Prerequisites

  1. vendure server를 설치해야 한다.

절차

  1. vendure server 설치

  2. plugin 만들고

  3. bootstrap config 에 추가 : <proj_root>\src\vendure-config.ts 에 추가하면 된다.

  4. db migration

    • yarn migration:create <migration_file_name>
    • yarn migration:run
  5. 서버 재시작

  6. http://localhost:3000/admin-api 에서 다음 mutation 을 실행하면 된다.

    mutation {
      addRandomCat(id: "1") {
        id
        name
        customFields {
          catImageUrl
        }
      }
    }

plugin 추가하고 적용해보기

  1. RandomCat plugin-full-example
  2. <proj_root>/src/vendure-config.ts 에 추가 : 이것으로 vendure server에서 plugin 을 사용할 수 있게 된다.
  3. 서버 재시작

아래 plugin 을 아무 곳에나 넣는다. 여기서는 /src/plugins/randomcat안에 넣었다.

// ------------------------
// <proj_root>\src\plugins\randomcatrandomcat.plugin.ts
// ------------------------
import { Injectable } from '@nestjs/common';
import { Args, Mutation, Resolver } from '@nestjs/graphql';
import gql from 'graphql-tag';
import http from 'http';
import { Allow, Ctx, PluginCommonModule, ProductService, 
    RequestContext, VendureConfig, VendurePlugin } from '@vendure/core';
import { Permission } from '@vendure/common/lib/generated-types';

const schemaExtension = gql`
    extend type Mutation {
        addRandomCat(id: ID!): Product!
    }
`;

@Injectable()
export class CatFetcher {
  /** Fetch a random cat image url from random.cat */
  fetchCat(): Promise<string> {
    return new Promise((resolve) => {
      http.get('http://fastly.picsum.photos/id/237/200/300.jpg?hmac=TmmQSbShHz9CdQm0NkEjx1Dyh_Y984R9LpNrpvH2D_U', (resp) => {
        let data = '';
        resp.on('data', chunk => data += chunk);
        resp.on('end', () => {
          // 수정
          // return resolve(JSON.parse(data).file)
          return resolve('http://fastly.picsum.photos/id/237/200/300.jpg?hmac=TmmQSbShHz9CdQm0NkEjx1Dyh_Y984R9LpNrpvH2D_U')
        })
          ;
      });
    });
  }
}

@Resolver()
export class RandomCatResolver {
  constructor(private productService: ProductService, 
              private catFetcher: CatFetcher) {}

  @Mutation()
  // 수정
  // @Allow(Permission.UpdateCatalog)
  @Allow(Permission.Public)
  async addRandomCat(@Ctx() ctx: RequestContext, @Args() args: any) {
    const catImageUrl = await this.catFetcher.fetchCat();
    return this.productService.update(ctx, {
      id: args.id,
      customFields: { catImageUrl },
    });
  }
}

@VendurePlugin({
  imports: [PluginCommonModule],
  providers: [CatFetcher],
  adminApiExtensions: {
    schema: schemaExtension,
    resolvers: [RandomCatResolver],
  },
  configuration: config => {
    config.customFields.Product.push({
      type: 'string',
      name: 'catImageUrl',
    });
    return config;
  },
  compatibility: '^2.0.0',
})
export class RandomCatPlugin {}

다음처럼 config 으 plugins 부분에 새롭게 추가된 plugin 을 추가해주면 된다.

// 
// <proj_root>/src/vendure-config.ts
// 
...
import { RandomCatPlugin } from './plugins/randomcat/randomcat.plugin';

const IS_DEV = process.env.APP_ENV === 'dev';

export const config: VendureConfig = {
    apiOptions: {
        ...
    },
    authOptions: {
        ...
    },
    dbConnectionOptions: {
        ...
    },
    paymentOptions: {
        ...
    },
    // When adding or altering custom field definitions, the database will
    // need to be updated. See the "Migrations" section in README.md.
    customFields: {},
    plugins: [
        ...
        // --------------------------------------------
        // 여기에 추가한다.
        // --------------------------------------------
        RandomCatPlugin,
    ],
};

이제 서버를 다시 시작하면 된다. 그러면 노란색으로 db 를 변경해야 된다고 나온다.

db field 추가하기(DB Migration)

이제 저 노란 warning 을 없애보자. 즉 database 에 변경사항을 적용해보자.

ref. 4(Migrations | Vendure docs) 에 보면 설명이 있다.

기본적으로 <root>/src/vendure-config.ts 에 있는 설정값 dbConnectionOptions을 이용하게 된다. 여기에 migrations 정보가 있다. 이곳에 migrataion file을 만들게 된다.

migration command 는 package.json에 있다. 참고로 내부적으로 TypeORM 의 migration 기능을 사용한다.

migration:generate

yarn migration:generate <migration_file_name> 하면 현재 VendureConfig 와 현재의 database의 차이를 보고 migration file을 만들어주게 된다. <migration_file_name> 는 아무 string이나 넣으면 된다. 되도록 migration 을 설명하는 내용이면 좋다.

yarn migration:generate alter_product_catimageurl

migration:run

이제 이 만들어진 migration 을 실행하자. yarn migration:run 을 하면 된다.

yarn migration:run
D:\a\prog\real-world-vendure\v2\twin-cat>yarn migration:generate alter_product_catimageurl
yarn run v1.22.19
$ ts-node migration generate alter_product_catimageurl
Migration src\migrations\1692419711349-alter_product_catimageurl.ts has been generated successfully.
Done in 6.06s.

D:\a\prog\real-world-vendure\v2\twin-cat>yarn migration:run
yarn run v1.22.19
$ ts-node migration run
Successfully ran migration: alterProductCatimageurl1692419711349
Done in 5.93s.

아래처럼 customFieldsCatimageurl 이 생겼다.

migration:revert

yarn migration:revert

실패하는 경우

실패하면 기본적으로 rollback을 하도록 되어 있다. 다만 migration 여러개를 하던중에 문제가 발생한 경우 rollback을 하지만, MySQL/MariaDB 에서는 여러 transaction 을 rollback 하는 것을 지원하지 못한다고 한다.(?) Run migrations 을 참고하자.

사용하는 db table

db의 migrations라는 table을 사용해서 migration 이 어디까지 진행됐는지등을 파악한다.

Reference

  1. GitHub - vendure-ecommerce/plugin-template: A template for creating re-usable Vendure plugins
  2. Writing a Vendure Plugin | Vendure docs
  3. real-world-vendure/src/plugins/reviews at master · vendure-ecommerce/real-world-vendure · GitHub
  4. Migrations | Vendure docs

[컴] vendure 2.0 설치 및 실행

vendure server 실행하기 / vendure server 2.0 실행하기

vendure 2.0 설치 및 실행

  1. npx @vendure/create@next twin-cat : 이때 알아서 node_modules 까지 설치가 된다.
  2. cd twin-cat
  3. yarn dev


D:\a\prog\real-world-vendure\v2>npx @vendure/create@next twin-cat
Need to install the following packages:
  @vendure/create@2.1.0-next.0
Ok to proceed? (y) y

Port 3000 is in use. Please make it available and then re-try.

D:\a\prog\real-world-vendure\v2>npx @vendure/create@next twin-cat

T  Let's create a Vendure App ✨ v2.1.0-next.0
|
o  Which database are you using?
|  Postgres
|
o  What's the database host address?
|  localhost
|
o  What port is the database listening on?
|  5432
|
o  What's the name of the database?
|  twin-cat
|
o  What's the schema name we should use?
|  public
|
o  What's the database user name?
|  myuser
|
o  What's the database password?
|  mypassword
|
o  What identifier do you want to use for the superadmin user?
|  superadmin
|
o  What password do you want to use for the superadmin user?
|  superadmin
|
o  Populate with some sample product data?
|  yes
|
|
o  Created package.json
|
o  Successfully installed 7 dependencies
|
o  Successfully installed 2 dev dependencies
|
o  Generated app scaffold
|
|
o  Server successfully initialized and populated
|
o   ------------------------------------------------+
|                                                   |
|  Success! Created a new Vendure server at:        |
|                                                   |
|                                                   |
|  D:\a\prog\real-world-vendure\v2\twin-cat  |
|                                                   |
|                                                   |
|  We suggest that you start by typing:             |
|                                                   |
|                                                   |
|  $ cd twin-cat                                    |
|  $ yarn dev                                       |
|                                                   |
+---------------------------------------------------+
|
—  Happy hacking!

D:\a\prog\real-world-vendure\v2>cd twin-cat

D:\a\prog\real-world-vendure\v2\twin-cat>yarn dev
yarn run v1.22.19
$ concurrently yarn:dev:*
$ ts-node ./src/index.ts
$ ts-node ./src/index-worker.ts
[worker] info 23. 8. 19. 오후 1:04 - [Vendure Worker] Bootstrapping Vendure Worker (pid: 12092)...
[server] info 23. 8. 19. 오후 1:04 - [Vendure Server] Bootstrapping Vendure Server (pid: 6404)...
[worker] info 23. 8. 19. 오후 1:04 - [Vendure Worker] Vendure Worker is ready
[worker] info 23. 8. 19. 오후 1:04 - [JobQueue] Starting queue: apply-collection-filters
[worker] info 23. 8. 19. 오후 1:04 - [JobQueue] Starting queue: update-search-index
[worker] info 23. 8. 19. 오후 1:04 - [JobQueue] Starting queue: send-email
[server] info 23. 8. 19. 오후 1:04 - [AdminUiPlugin] Creating admin ui middleware (prod mode)
[server] info 23. 8. 19. 오후 1:04 - [AssetServerPlugin] Creating asset server middleware
[server] info 23. 8. 19. 오후 1:04 - [EmailPlugin] Creating dev mailbox middleware
[server] info 23. 8. 19. 오후 1:04 - [RoutesResolver] HealthController {/health}:
[server] info 23. 8. 19. 오후 1:04 - [RouterExplorer] Mapped {/health, GET} route
[server] info 23. 8. 19. 오후 1:04 - [GraphQLModule] Mapped {/shop-api, POST} route
[server] info 23. 8. 19. 오후 1:04 - [GraphQLModule] Mapped {/admin-api, POST} route
[server] info 23. 8. 19. 오후 1:04 - [NestApplication] Nest application successfully started
[server] info 23. 8. 19. 오후 1:04 - [Vendure Server] =======================================================
[server] info 23. 8. 19. 오후 1:04 - [Vendure Server] Vendure server (v2.1.0-next.0) now running on port 3000
[server] info 23. 8. 19. 오후 1:04 - [Vendure Server] -------------------------------------------------------
[server] info 23. 8. 19. 오후 1:04 - [Vendure Server] Shop API:     http://localhost:3000/shop-api
[server] info 23. 8. 19. 오후 1:04 - [Vendure Server] Admin API:    http://localhost:3000/admin-api
[server] info 23. 8. 19. 오후 1:04 - [Vendure Server] Asset server: http://localhost:3000/assets
[server] info 23. 8. 19. 오후 1:04 - [Vendure Server] Dev mailbox:  http://localhost:3000/mailbox
[server] info 23. 8. 19. 오후 1:04 - [Vendure Server] Admin UI:     http://localhost:3000/admin
[server] info 23. 8. 19. 오후 1:04 - [Vendure Server] =======================================================

Reference

  1. Migrating to Vendure v2.0 · vendure-ecommerce/vendure · Discussion #1991 · GitHub

[컴][db] postgresql meta command

 

postgres / 포스트그레스 / db command / table 보는 법 / db 보는 법 / 모든 데이터베이스 / 테이블 보는 법 / sql 명령어 / beaver 에서 보는 법

postgresql meta command

postgresql 에선 mysql 에서 show tables, show databases 같은 명령어를 직접 제공하지 않는다. meta command 라는 것을 제공해서, 비슷한 기능을 제공한다. 몇몇 meta command 는 실질적으로 특정 sql 로 변환돼서 postgresql 에서 실행된다.

예를 들면 아래처럼 말이다. (-E option 이 sql 을 보여주는 옵션이다.)

cd d:\a\apps\PostgreSQL\13\bin
psql -E -h localhost -U postgres


postgres=# \l
********** 쿼리 **********
SELECT d.datname as "Name",
       pg_catalog.pg_get_userbyid(d.datdba) as "Owner",
       pg_catalog.pg_encoding_to_char(d.encoding) as "Encoding",
       d.datcollate as "Collate",
       d.datctype as "Ctype",
       pg_catalog.array_to_string(d.datacl, E'\n') AS "Access privileges"
FROM pg_catalog.pg_database d
ORDER BY 1;
**************************

                                       데이터베이스 목록
    이름     |  소유주  | 인코딩 |     Collate      |      Ctype       |      액세스 권한
-------------+----------+--------+------------------+------------------+-----------------------
 postgres    | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 |
 mytest      | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 |
 mytest-dev  | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 |
 mytest-dog  | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 |
 template0   | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 | =c/postgres          +
             |          |        |                  |                  | postgres=CTc/postgres
 template1   | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 | =c/postgres          +
             |          |        |                  |                  | postgres=CTc/postgres
 testdb      | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 |
 twin-cat    | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 |
 userhabitdb | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 |
(9개 행)

다른 meta commnad 들

  • \c [데이터베이스 이름] - 지정된 데이터베이스에 연결한다.
  • \l - 모든 데이터베이스를 나열한다.
  • \d - 테이블, 뷰 및 시퀀스를 표시한다.
    • \dt - 테이블만 표시한다.
    • \dv - 뷰를 표시한다.
    • \dm - 머티리얼라이즈드 뷰를 표시한다.
    • \di - 인덱스를 표시한다.
    • \dn - 스키마를 표시한다.
    • \dT - 데이터 타입을 표시한다.
    • 기타 등등
  • \sv [뷰 이름] - 뷰의 정의를 표시한다.
  • \x - 확장된 디스플레이를 전환한다. 많은 열이 있는 테이블에 유용한다.
    • on/off로 토글하거나 auto로 설정할 수 있습니다.
  • \set - 모든 내부 변수를 나열한다.
    • \set [이름] [값] - 새로운 내부 변수를 설정한다.
    • \unset [이름] - 내부 변수를 삭제한다.
  • \cd - psql이 작업하는 디렉터리를 변경한다.
  • ! [명령] - 셸 명령을 실행한다.
    • 예: ! ls 또는 ! pwd
  • \timing - 쿼리의 실행 시간 측정을 전환한다.
  • \echo [메시지] - 메시지를 콘솔에 출력한다.
  • \copy - 파일로 복사한다.
  • \i [파일명] - 파일에서 명령을 실행한다.
  • \o [파일] - 콘솔 대신 파일로 출력을 작성한다.
  • \q - psql을 종료한다.

Reference

  1. Using meta commands in psql

[컴] vendure plugin 사용처

vendure extension 어디에 사용할까 / 어떻게 사용할까

vendure plugin 사용처

vendure plugin 의 사용

  1. worker에서 동작할 task 를 만들때: Plugin 은 Vendure Worker 에 의해 수행될 logic 을 정의할 수 있다. 이것은 long-running task들 또는 resource가 많이 드는 task 들에 적합하다.

  2. server 설정 변경할때 : Plugin 은 configuration metadata property 를 통해 server configuration 의 모든 부분을 수정할 수 있다.

  3. GraphQL API들을 확장 : Plugin 은 shopApiExtensions metadata propertyadminApiExtensions metadata property 을 통해 GraphQL API들을 확장할 수 있다.

  4. vendure 서버에 로직 추가 할때 : 플러그인은 PluginCommonModule을 import 해서 Vendure와 상호작용할 수 있으며, 이를 통해 core Vendure 서비스를 inject할 수 있습니다. 이 core vendure service 는 데이터베이스와의 모든 상호작용 및 비즈니스 로직을 담당한다.

    • 추가적으로, 플러그인은 entities metadata property 을 통해 새로운 database entity를 정의할 수 있으며,
    • 다른 Nestjs 모듈과 마찬가지로 다른 공급자 및 컨트롤러를 정의할 수도 있습니다.
  5. aws 등의 외부서비스와의 연동 : Plugin 은 임의의 코드를 실행할 수 있으므로 외부 서비스를 사용할 수 있게 해준다. 예를 들어 Plugin 은 cloud storage provider, payment gateway 또는 비디오 인코딩 서비스와 연결할 수 있다.

Reference

  1. Writing a Vendure Plugin | Vendure docs

[컴][db] PostgreSQL 의 MVCC

 

postgresql / lock mechanism /

PostgreSQL 의 MVCC

postgres 는 ‘여러버전 동시 제어(Multiversion Concurrency Control, MVCC)’ 를 구현했다.

그래서 reading 과 writing 의 lock 이 관련이 없다. 즉, reading 을 위해 lock 이 걸려도, write 를 하는데 지장이 없다. write 은 새로운 version 의 row를 만들테니.

다음은 ref.1 의 정리다.

  • 각 SQL 문은 기초 데이터의 현재 상태와 관계없이 얼마 전의 데이터 스냅샷(데이터베이스 버전)을 보게 된다.
  • 같은 row에 대해 동시에 transaction 들이 발생하면 data 가 일관되지 않게 된다. 이런 일관되지 않은 data(inconsistent data) 를 statement 가 바라보게 되는 것을 막는다.
    • 이것이 각 데이터베이스 세션에 대해 transaction isolation을 제공하게 된다.
  • MVCC는 기존 데이터베이스 시스템의 locking methodologies을 피함으로써 다중 사용자 환경에서 합리적인 성능을 발휘할 수 있도록 lock contention을 최소화한다.
  • lock 대신에 MVCC 를 이용할때의 주요장점
    • MVCC에서 데이터 쿼리(read)를 위해 획득한 lock이 데이터 write를 위해 획득한 lock과 충돌하지 않기 때문에 read가 write를 차단하지 않고 write가 read를 차단하지 않는다는 것이다.
    • PostgreSQL은 Serializable Snapshot Isolation(SSI) level을 사용하여 가장 strictest level의 transaction isolation를 제공하는 경우에도 계속 이것을 보장한다.
  • 테이블 및 row level의 lock 기능도 PostgreSQL에서 사용할 수 있다.
    • 일반적으로 full transaction isolation이 필요하지 않고 특정 conflict 지점을 명시적으로(explicitly) 관리하는 것을 선호하는 애플리케이션들은 이것을 사용하면 된다.
  • 그러나 MVCC를 적절히 사용하면 일반적으로 lock보다 더 나은 성능을 제공한다.
  • 또한 application-defined advisory lock들은, ’single transaction에만 관련이 있는 것이 아닌 lock들’을 획득할 수 있는 메커니즘을 제공한다.

Refrence

  1. PostgreSQL: Documentation: 15: 13.1. Introduction

[컴] Wayland 정보 몇가지

Wayland 정보 몇가지

Wayland 에 관한 정보 몇가지 from ref.1

  • wayland 는 그냥 protocol 이다. Wayland protocol을 구현한 display server를 Wayland Compositor 라고 부른다.[ref. 2]
  • 이 wayland 의 reference 구현체가 Weston 이다.
  • composite을 좀 더 효율적으로 하도록 디자인됐다. X 에서는 extension 으로 composite을 했다. XComposite
  • 그런데, 전체화면에서도 composite을 하도록 돼 있어서 그것이 전체화면에서 약간의 오버헤드가 된다. 전체화면에서 이것을 하지 않도록 app에서 구현해야 한다.
  • NVidia driver로는 사용하기 어렵다. 다른 graphics card들은 GBM(Generic Buffer Managerment) 를 사용하는데, Nvidia 는 EGL 이라는 방법을 사용
  • server와 client 는 IPC 로 통신한다.

stacking manager 와의 비교

stacking window manager에서 window 끼리 overlapping 이 가능해졌다. 이전에는 window 들이 tile 처럼 화면에 overlapping 이 안되게 배치됐다.

window 가 repaint 하라는 message를 보냈는데, 여러가지 이유로 처리를 못하는 경우 이 repainting 작업이 잘못될 수 있다.(become corrupted) 그러면 그 화면이 안그려지거나 할 것이다.

compositing window manager 에서는 이 경우 마지막 repaint 가 계속 그려진채로 남겨지고, window 가 어두워질 것이다.(me : 즉, 그리는 것에 대한 부분을 compositing window manager가 담당한다. window manager는 window 가 담당한다.)

  • 여기에서 stacking manager 의 동작을 볼 수 있다.

다른 것은 shadow 같은 것들이 있다. 이것을 window 가 처리해야 하겠지만, composite에서는 window 를 그려넣을때 composite manager 가 처리해준다.

X windows system 과의 비교

Greefield project

browser에서 Wayland composite을 구현했다.

surface flinger vs wayland

ios

Reference

  1. Using Linux With Wayland? What You Need to Know, 2019-12-20
  2. Wayland (protocol) - Wikipedia