mirror of
https://github.com/khairul169/github-leaderboard.git
synced 2025-04-28 15:39:31 +07:00
feat: migrate db to postgres
This commit is contained in:
parent
0142224f60
commit
8ff59ba6b3
@ -1,14 +1,15 @@
|
|||||||
# App
|
# App
|
||||||
HOST=
|
HOST=
|
||||||
PORT=
|
PORT=
|
||||||
|
JWT_SECRET=supersecretkey
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
DATABASE_PATH=
|
DATABASE_PATH=postgres://postgres:postgres@127.0.0.1:5432/github_leaderboard
|
||||||
|
|
||||||
# Auth
|
# Github API
|
||||||
GITHUB_CLIENT_ID=
|
GITHUB_CLIENT_ID=
|
||||||
GITHUB_SECRET_KEY=
|
GITHUB_SECRET_KEY=
|
||||||
JWT_SECRET=supersecretkey
|
GITHUB_DEFAULT_TOKEN=
|
||||||
|
|
||||||
# Queue Worker
|
# Queue Worker
|
||||||
QUEUE_CONCURRENCY=1
|
QUEUE_CONCURRENCY=1
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
"drizzle-orm": "^0.32.2",
|
"drizzle-orm": "^0.32.2",
|
||||||
"hono": "^4.5.4",
|
"hono": "^4.5.4",
|
||||||
"pino": "^9.3.2",
|
"pino": "^9.3.2",
|
||||||
|
"postgres": "^3.4.4",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-daisyui": "^5.0.3",
|
"react-daisyui": "^5.0.3",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
|
203
pnpm-lock.yaml
generated
203
pnpm-lock.yaml
generated
@ -25,13 +25,16 @@ importers:
|
|||||||
version: 1.11.12
|
version: 1.11.12
|
||||||
drizzle-orm:
|
drizzle-orm:
|
||||||
specifier: ^0.32.2
|
specifier: ^0.32.2
|
||||||
version: 0.32.2(@types/react@18.3.3)(better-sqlite3@11.1.2)(bun-types@1.1.17)(react@18.3.1)
|
version: 0.32.2(@types/pg@8.11.6)(@types/react@18.3.3)(better-sqlite3@11.1.2)(bun-types@1.1.17)(pg@8.12.0)(postgres@3.4.4)(react@18.3.1)
|
||||||
hono:
|
hono:
|
||||||
specifier: ^4.5.4
|
specifier: ^4.5.4
|
||||||
version: 4.5.4
|
version: 4.5.4
|
||||||
pino:
|
pino:
|
||||||
specifier: ^9.3.2
|
specifier: ^9.3.2
|
||||||
version: 9.3.2
|
version: 9.3.2
|
||||||
|
postgres:
|
||||||
|
specifier: ^3.4.4
|
||||||
|
version: 3.4.4
|
||||||
react:
|
react:
|
||||||
specifier: ^18.3.1
|
specifier: ^18.3.1
|
||||||
version: 18.3.1
|
version: 18.3.1
|
||||||
@ -987,6 +990,9 @@ packages:
|
|||||||
'@types/node@20.12.14':
|
'@types/node@20.12.14':
|
||||||
resolution: {integrity: sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==}
|
resolution: {integrity: sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==}
|
||||||
|
|
||||||
|
'@types/pg@8.11.6':
|
||||||
|
resolution: {integrity: sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==}
|
||||||
|
|
||||||
'@types/prop-types@15.7.12':
|
'@types/prop-types@15.7.12':
|
||||||
resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==}
|
resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==}
|
||||||
|
|
||||||
@ -1908,6 +1914,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
|
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
|
||||||
|
obuf@1.1.2:
|
||||||
|
resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==}
|
||||||
|
|
||||||
on-exit-leak-free@2.1.2:
|
on-exit-leak-free@2.1.2:
|
||||||
resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==}
|
resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==}
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
@ -1963,6 +1972,48 @@ packages:
|
|||||||
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
|
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
pg-cloudflare@1.1.1:
|
||||||
|
resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==}
|
||||||
|
|
||||||
|
pg-connection-string@2.6.4:
|
||||||
|
resolution: {integrity: sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==}
|
||||||
|
|
||||||
|
pg-int8@1.0.1:
|
||||||
|
resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
|
||||||
|
engines: {node: '>=4.0.0'}
|
||||||
|
|
||||||
|
pg-numeric@1.0.2:
|
||||||
|
resolution: {integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
|
pg-pool@3.6.2:
|
||||||
|
resolution: {integrity: sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==}
|
||||||
|
peerDependencies:
|
||||||
|
pg: '>=8.0'
|
||||||
|
|
||||||
|
pg-protocol@1.6.1:
|
||||||
|
resolution: {integrity: sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==}
|
||||||
|
|
||||||
|
pg-types@2.2.0:
|
||||||
|
resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
|
pg-types@4.0.2:
|
||||||
|
resolution: {integrity: sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
pg@8.12.0:
|
||||||
|
resolution: {integrity: sha512-A+LHUSnwnxrnL/tZ+OLfqR1SxLN3c/pgDztZ47Rpbsd4jUytsTtwQo/TLPRzPJMp/1pbhYVhH9cuSZLAajNfjQ==}
|
||||||
|
engines: {node: '>= 8.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
pg-native: '>=3.0.1'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
pg-native:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
pgpass@1.0.5:
|
||||||
|
resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==}
|
||||||
|
|
||||||
picocolors@1.0.1:
|
picocolors@1.0.1:
|
||||||
resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
|
resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
|
||||||
|
|
||||||
@ -2033,6 +2084,45 @@ packages:
|
|||||||
resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==}
|
resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==}
|
||||||
engines: {node: ^10 || ^12 || >=14}
|
engines: {node: ^10 || ^12 || >=14}
|
||||||
|
|
||||||
|
postgres-array@2.0.0:
|
||||||
|
resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
|
postgres-array@3.0.2:
|
||||||
|
resolution: {integrity: sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
postgres-bytea@1.0.0:
|
||||||
|
resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
postgres-bytea@3.0.0:
|
||||||
|
resolution: {integrity: sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==}
|
||||||
|
engines: {node: '>= 6'}
|
||||||
|
|
||||||
|
postgres-date@1.0.7:
|
||||||
|
resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
postgres-date@2.1.0:
|
||||||
|
resolution: {integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
postgres-interval@1.2.0:
|
||||||
|
resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
postgres-interval@3.0.0:
|
||||||
|
resolution: {integrity: sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
postgres-range@1.1.4:
|
||||||
|
resolution: {integrity: sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==}
|
||||||
|
|
||||||
|
postgres@3.4.4:
|
||||||
|
resolution: {integrity: sha512-IbyN+9KslkqcXa8AO9fxpk97PA4pzewvpi2B3Dwy9u4zpV32QicaEdgmF3eSQUzdRk7ttDHQejNgAEr4XoeH4A==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
prebuild-install@7.1.2:
|
prebuild-install@7.1.2:
|
||||||
resolution: {integrity: sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==}
|
resolution: {integrity: sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -2484,6 +2574,10 @@ packages:
|
|||||||
wrappy@1.0.2:
|
wrappy@1.0.2:
|
||||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||||
|
|
||||||
|
xtend@4.0.2:
|
||||||
|
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
||||||
|
engines: {node: '>=0.4'}
|
||||||
|
|
||||||
y18n@5.0.8:
|
y18n@5.0.8:
|
||||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -3089,6 +3183,13 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 5.26.5
|
undici-types: 5.26.5
|
||||||
|
|
||||||
|
'@types/pg@8.11.6':
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 20.12.14
|
||||||
|
pg-protocol: 1.6.1
|
||||||
|
pg-types: 4.0.2
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@types/prop-types@15.7.12': {}
|
'@types/prop-types@15.7.12': {}
|
||||||
|
|
||||||
'@types/react-dom@18.3.0':
|
'@types/react-dom@18.3.0':
|
||||||
@ -3516,11 +3617,14 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
drizzle-orm@0.32.2(@types/react@18.3.3)(better-sqlite3@11.1.2)(bun-types@1.1.17)(react@18.3.1):
|
drizzle-orm@0.32.2(@types/pg@8.11.6)(@types/react@18.3.3)(better-sqlite3@11.1.2)(bun-types@1.1.17)(pg@8.12.0)(postgres@3.4.4)(react@18.3.1):
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
|
'@types/pg': 8.11.6
|
||||||
'@types/react': 18.3.3
|
'@types/react': 18.3.3
|
||||||
better-sqlite3: 11.1.2
|
better-sqlite3: 11.1.2
|
||||||
bun-types: 1.1.17
|
bun-types: 1.1.17
|
||||||
|
pg: 8.12.0
|
||||||
|
postgres: 3.4.4
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
|
|
||||||
eastasianwidth@0.2.0: {}
|
eastasianwidth@0.2.0: {}
|
||||||
@ -4037,6 +4141,9 @@ snapshots:
|
|||||||
|
|
||||||
object-hash@3.0.0: {}
|
object-hash@3.0.0: {}
|
||||||
|
|
||||||
|
obuf@1.1.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
on-exit-leak-free@2.1.2: {}
|
on-exit-leak-free@2.1.2: {}
|
||||||
|
|
||||||
once@1.4.0:
|
once@1.4.0:
|
||||||
@ -4090,6 +4197,62 @@ snapshots:
|
|||||||
|
|
||||||
path-type@4.0.0: {}
|
path-type@4.0.0: {}
|
||||||
|
|
||||||
|
pg-cloudflare@1.1.1:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
pg-connection-string@2.6.4:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
pg-int8@1.0.1:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
pg-numeric@1.0.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
pg-pool@3.6.2(pg@8.12.0):
|
||||||
|
dependencies:
|
||||||
|
pg: 8.12.0
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
pg-protocol@1.6.1:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
pg-types@2.2.0:
|
||||||
|
dependencies:
|
||||||
|
pg-int8: 1.0.1
|
||||||
|
postgres-array: 2.0.0
|
||||||
|
postgres-bytea: 1.0.0
|
||||||
|
postgres-date: 1.0.7
|
||||||
|
postgres-interval: 1.2.0
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
pg-types@4.0.2:
|
||||||
|
dependencies:
|
||||||
|
pg-int8: 1.0.1
|
||||||
|
pg-numeric: 1.0.2
|
||||||
|
postgres-array: 3.0.2
|
||||||
|
postgres-bytea: 3.0.0
|
||||||
|
postgres-date: 2.1.0
|
||||||
|
postgres-interval: 3.0.0
|
||||||
|
postgres-range: 1.1.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
pg@8.12.0:
|
||||||
|
dependencies:
|
||||||
|
pg-connection-string: 2.6.4
|
||||||
|
pg-pool: 3.6.2(pg@8.12.0)
|
||||||
|
pg-protocol: 1.6.1
|
||||||
|
pg-types: 2.2.0
|
||||||
|
pgpass: 1.0.5
|
||||||
|
optionalDependencies:
|
||||||
|
pg-cloudflare: 1.1.1
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
pgpass@1.0.5:
|
||||||
|
dependencies:
|
||||||
|
split2: 4.2.0
|
||||||
|
optional: true
|
||||||
|
|
||||||
picocolors@1.0.1: {}
|
picocolors@1.0.1: {}
|
||||||
|
|
||||||
picomatch@2.3.1: {}
|
picomatch@2.3.1: {}
|
||||||
@ -4173,6 +4336,39 @@ snapshots:
|
|||||||
picocolors: 1.0.1
|
picocolors: 1.0.1
|
||||||
source-map-js: 1.2.0
|
source-map-js: 1.2.0
|
||||||
|
|
||||||
|
postgres-array@2.0.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
postgres-array@3.0.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
postgres-bytea@1.0.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
postgres-bytea@3.0.0:
|
||||||
|
dependencies:
|
||||||
|
obuf: 1.1.2
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
postgres-date@1.0.7:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
postgres-date@2.1.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
postgres-interval@1.2.0:
|
||||||
|
dependencies:
|
||||||
|
xtend: 4.0.2
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
postgres-interval@3.0.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
postgres-range@1.1.4:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
postgres@3.4.4: {}
|
||||||
|
|
||||||
prebuild-install@7.1.2:
|
prebuild-install@7.1.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
detect-libc: 2.0.3
|
detect-libc: 2.0.3
|
||||||
@ -4625,6 +4821,9 @@ snapshots:
|
|||||||
|
|
||||||
wrappy@1.0.2: {}
|
wrappy@1.0.2: {}
|
||||||
|
|
||||||
|
xtend@4.0.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
y18n@5.0.8: {}
|
y18n@5.0.8: {}
|
||||||
|
|
||||||
yaml@2.5.0: {}
|
yaml@2.5.0: {}
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
import { drizzle } from "drizzle-orm/bun-sqlite";
|
import { drizzle } from "drizzle-orm/postgres-js";
|
||||||
import { Database } from "bun:sqlite";
|
import postgres from "postgres";
|
||||||
import * as schema from "../models";
|
import * as schema from "../models";
|
||||||
|
|
||||||
const DATABASE_PATH = import.meta.env.DATABASE_PATH || "./data.db";
|
const DATABASE_PATH = import.meta.env.DATABASE_PATH;
|
||||||
|
if (!DATABASE_PATH) {
|
||||||
|
throw new Error("DATABASE_PATH is not set");
|
||||||
|
}
|
||||||
|
|
||||||
const sqlite = new Database(DATABASE_PATH);
|
const queryClient = postgres(DATABASE_PATH);
|
||||||
const db = drizzle(sqlite, { schema });
|
const db = drizzle(queryClient, { schema });
|
||||||
|
|
||||||
export default db;
|
export default db;
|
||||||
|
59
server/db/migrations/0000_round_hellion.sql
Normal file
59
server/db/migrations/0000_round_hellion.sql
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS "repository_languages" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"repo_id" integer NOT NULL,
|
||||||
|
"name" varchar NOT NULL,
|
||||||
|
"percentage" double precision NOT NULL
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "repositories" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"user_id" integer NOT NULL,
|
||||||
|
"name" varchar NOT NULL,
|
||||||
|
"uri" varchar NOT NULL,
|
||||||
|
"language" varchar NOT NULL,
|
||||||
|
"stars" integer NOT NULL,
|
||||||
|
"forks" integer NOT NULL,
|
||||||
|
"last_update" varchar NOT NULL,
|
||||||
|
"contributors" jsonb,
|
||||||
|
"is_pending" boolean DEFAULT false NOT NULL,
|
||||||
|
"is_error" boolean DEFAULT false NOT NULL,
|
||||||
|
"created_at" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||||
|
"updated_at" timestamp NOT NULL
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE TABLE IF NOT EXISTS "users" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"username" varchar NOT NULL,
|
||||||
|
"name" varchar NOT NULL,
|
||||||
|
"avatar" varchar,
|
||||||
|
"location" varchar,
|
||||||
|
"followers" integer DEFAULT 0 NOT NULL,
|
||||||
|
"following" integer DEFAULT 0 NOT NULL,
|
||||||
|
"achievements" jsonb DEFAULT '[]'::jsonb,
|
||||||
|
"points" integer DEFAULT 0 NOT NULL,
|
||||||
|
"commits" integer DEFAULT 0 NOT NULL,
|
||||||
|
"line_of_codes" integer DEFAULT 0 NOT NULL,
|
||||||
|
"github_id" integer,
|
||||||
|
"access_token" varchar,
|
||||||
|
"created_at" timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||||
|
"updated_at" timestamp NOT NULL,
|
||||||
|
CONSTRAINT "users_username_unique" UNIQUE("username"),
|
||||||
|
CONSTRAINT "users_github_id_unique" UNIQUE("github_id")
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "repository_languages" ADD CONSTRAINT "repository_languages_repo_id_repositories_id_fk" FOREIGN KEY ("repo_id") REFERENCES "public"."repositories"("id") ON DELETE no action ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "repositories" ADD CONSTRAINT "repositories_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
CREATE INDEX IF NOT EXISTS "repository_languages_name_idx" ON "repository_languages" USING btree ("name");--> statement-breakpoint
|
||||||
|
CREATE INDEX IF NOT EXISTS "repositories_name_idx" ON "repositories" USING btree ("name");--> statement-breakpoint
|
||||||
|
CREATE INDEX IF NOT EXISTS "repositories_uri_idx" ON "repositories" USING btree ("uri");--> statement-breakpoint
|
||||||
|
CREATE INDEX IF NOT EXISTS "repositories_language_idx" ON "repositories" USING btree ("language");
|
@ -1,49 +0,0 @@
|
|||||||
CREATE TABLE `repository_languages` (
|
|
||||||
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
||||||
`repo_id` integer NOT NULL,
|
|
||||||
`name` text NOT NULL,
|
|
||||||
`percentage` real NOT NULL,
|
|
||||||
FOREIGN KEY (`repo_id`) REFERENCES `repositories`(`id`) ON UPDATE no action ON DELETE no action
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE `repositories` (
|
|
||||||
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
||||||
`user_id` integer NOT NULL,
|
|
||||||
`name` text NOT NULL,
|
|
||||||
`uri` text NOT NULL,
|
|
||||||
`language` text NOT NULL,
|
|
||||||
`stars` integer NOT NULL,
|
|
||||||
`forks` integer NOT NULL,
|
|
||||||
`last_update` text NOT NULL,
|
|
||||||
`contributors` text,
|
|
||||||
`is_pending` integer DEFAULT false NOT NULL,
|
|
||||||
`is_error` integer DEFAULT false NOT NULL,
|
|
||||||
`created_at` text DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
|
||||||
`updated_at` text NOT NULL,
|
|
||||||
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE `users` (
|
|
||||||
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
||||||
`username` text NOT NULL,
|
|
||||||
`name` text NOT NULL,
|
|
||||||
`avatar` text,
|
|
||||||
`location` text,
|
|
||||||
`followers` integer DEFAULT 0 NOT NULL,
|
|
||||||
`following` integer DEFAULT 0 NOT NULL,
|
|
||||||
`achievements` text DEFAULT '[]',
|
|
||||||
`points` integer DEFAULT 0 NOT NULL,
|
|
||||||
`commits` integer DEFAULT 0 NOT NULL,
|
|
||||||
`line_of_codes` integer DEFAULT 0 NOT NULL,
|
|
||||||
`github_id` integer,
|
|
||||||
`access_token` text,
|
|
||||||
`created_at` text DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
|
||||||
`updated_at` text NOT NULL
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE INDEX `repository_languages_name_idx` ON `repository_languages` (`name`);--> statement-breakpoint
|
|
||||||
CREATE INDEX `repositories_name_idx` ON `repositories` (`name`);--> statement-breakpoint
|
|
||||||
CREATE INDEX `repositories_uri_idx` ON `repositories` (`uri`);--> statement-breakpoint
|
|
||||||
CREATE INDEX `repositories_language_idx` ON `repositories` (`language`);--> statement-breakpoint
|
|
||||||
CREATE UNIQUE INDEX `users_username_unique` ON `users` (`username`);--> statement-breakpoint
|
|
||||||
CREATE UNIQUE INDEX `users_github_id_unique` ON `users` (`github_id`);
|
|
@ -1,48 +1,53 @@
|
|||||||
{
|
{
|
||||||
"version": "6",
|
"id": "5131e61a-98fe-40ef-b206-62b860d39639",
|
||||||
"dialect": "sqlite",
|
|
||||||
"id": "a268ec23-239a-4d86-8830-2f3c1c2110df",
|
|
||||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||||
|
"version": "7",
|
||||||
|
"dialect": "postgresql",
|
||||||
"tables": {
|
"tables": {
|
||||||
"repository_languages": {
|
"public.repository_languages": {
|
||||||
"name": "repository_languages",
|
"name": "repository_languages",
|
||||||
|
"schema": "",
|
||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": "integer",
|
"type": "serial",
|
||||||
"primaryKey": true,
|
"primaryKey": true,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": true
|
|
||||||
},
|
},
|
||||||
"repo_id": {
|
"repo_id": {
|
||||||
"name": "repo_id",
|
"name": "repo_id",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"name": "name",
|
"name": "name",
|
||||||
"type": "text",
|
"type": "varchar",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"percentage": {
|
"percentage": {
|
||||||
"name": "percentage",
|
"name": "percentage",
|
||||||
"type": "real",
|
"type": "double precision",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {
|
"indexes": {
|
||||||
"repository_languages_name_idx": {
|
"repository_languages_name_idx": {
|
||||||
"name": "repository_languages_name_idx",
|
"name": "repository_languages_name_idx",
|
||||||
"columns": [
|
"columns": [
|
||||||
"name"
|
{
|
||||||
|
"expression": "name",
|
||||||
|
"isExpression": false,
|
||||||
|
"asc": true,
|
||||||
|
"nulls": "last"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"isUnique": false
|
"isUnique": false,
|
||||||
|
"concurrently": false,
|
||||||
|
"method": "btree",
|
||||||
|
"with": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"foreignKeys": {
|
"foreignKeys": {
|
||||||
@ -63,125 +68,137 @@
|
|||||||
"compositePrimaryKeys": {},
|
"compositePrimaryKeys": {},
|
||||||
"uniqueConstraints": {}
|
"uniqueConstraints": {}
|
||||||
},
|
},
|
||||||
"repositories": {
|
"public.repositories": {
|
||||||
"name": "repositories",
|
"name": "repositories",
|
||||||
|
"schema": "",
|
||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": "integer",
|
"type": "serial",
|
||||||
"primaryKey": true,
|
"primaryKey": true,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": true
|
|
||||||
},
|
},
|
||||||
"user_id": {
|
"user_id": {
|
||||||
"name": "user_id",
|
"name": "user_id",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"name": "name",
|
"name": "name",
|
||||||
"type": "text",
|
"type": "varchar",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"uri": {
|
"uri": {
|
||||||
"name": "uri",
|
"name": "uri",
|
||||||
"type": "text",
|
"type": "varchar",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"language": {
|
"language": {
|
||||||
"name": "language",
|
"name": "language",
|
||||||
"type": "text",
|
"type": "varchar",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"stars": {
|
"stars": {
|
||||||
"name": "stars",
|
"name": "stars",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"forks": {
|
"forks": {
|
||||||
"name": "forks",
|
"name": "forks",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"last_update": {
|
"last_update": {
|
||||||
"name": "last_update",
|
"name": "last_update",
|
||||||
"type": "text",
|
"type": "varchar",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"contributors": {
|
"contributors": {
|
||||||
"name": "contributors",
|
"name": "contributors",
|
||||||
"type": "text",
|
"type": "jsonb",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"is_pending": {
|
"is_pending": {
|
||||||
"name": "is_pending",
|
"name": "is_pending",
|
||||||
"type": "integer",
|
"type": "boolean",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false,
|
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
"is_error": {
|
"is_error": {
|
||||||
"name": "is_error",
|
"name": "is_error",
|
||||||
"type": "integer",
|
"type": "boolean",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false,
|
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
"created_at": {
|
"created_at": {
|
||||||
"name": "created_at",
|
"name": "created_at",
|
||||||
"type": "text",
|
"type": "timestamp",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false,
|
|
||||||
"default": "CURRENT_TIMESTAMP"
|
"default": "CURRENT_TIMESTAMP"
|
||||||
},
|
},
|
||||||
"updated_at": {
|
"updated_at": {
|
||||||
"name": "updated_at",
|
"name": "updated_at",
|
||||||
"type": "text",
|
"type": "timestamp",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {
|
"indexes": {
|
||||||
"repositories_name_idx": {
|
"repositories_name_idx": {
|
||||||
"name": "repositories_name_idx",
|
"name": "repositories_name_idx",
|
||||||
"columns": [
|
"columns": [
|
||||||
"name"
|
{
|
||||||
|
"expression": "name",
|
||||||
|
"isExpression": false,
|
||||||
|
"asc": true,
|
||||||
|
"nulls": "last"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"isUnique": false
|
"isUnique": false,
|
||||||
|
"concurrently": false,
|
||||||
|
"method": "btree",
|
||||||
|
"with": {}
|
||||||
},
|
},
|
||||||
"repositories_uri_idx": {
|
"repositories_uri_idx": {
|
||||||
"name": "repositories_uri_idx",
|
"name": "repositories_uri_idx",
|
||||||
"columns": [
|
"columns": [
|
||||||
"uri"
|
{
|
||||||
|
"expression": "uri",
|
||||||
|
"isExpression": false,
|
||||||
|
"asc": true,
|
||||||
|
"nulls": "last"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"isUnique": false
|
"isUnique": false,
|
||||||
|
"concurrently": false,
|
||||||
|
"method": "btree",
|
||||||
|
"with": {}
|
||||||
},
|
},
|
||||||
"repositories_language_idx": {
|
"repositories_language_idx": {
|
||||||
"name": "repositories_language_idx",
|
"name": "repositories_language_idx",
|
||||||
"columns": [
|
"columns": [
|
||||||
"language"
|
{
|
||||||
|
"expression": "language",
|
||||||
|
"isExpression": false,
|
||||||
|
"asc": true,
|
||||||
|
"nulls": "last"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"isUnique": false
|
"isUnique": false,
|
||||||
|
"concurrently": false,
|
||||||
|
"method": "btree",
|
||||||
|
"with": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"foreignKeys": {
|
"foreignKeys": {
|
||||||
@ -202,50 +219,45 @@
|
|||||||
"compositePrimaryKeys": {},
|
"compositePrimaryKeys": {},
|
||||||
"uniqueConstraints": {}
|
"uniqueConstraints": {}
|
||||||
},
|
},
|
||||||
"users": {
|
"public.users": {
|
||||||
"name": "users",
|
"name": "users",
|
||||||
|
"schema": "",
|
||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"type": "integer",
|
"type": "serial",
|
||||||
"primaryKey": true,
|
"primaryKey": true,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": true
|
|
||||||
},
|
},
|
||||||
"username": {
|
"username": {
|
||||||
"name": "username",
|
"name": "username",
|
||||||
"type": "text",
|
"type": "varchar",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"name": "name",
|
"name": "name",
|
||||||
"type": "text",
|
"type": "varchar",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"avatar": {
|
"avatar": {
|
||||||
"name": "avatar",
|
"name": "avatar",
|
||||||
"type": "text",
|
"type": "varchar",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"location": {
|
"location": {
|
||||||
"name": "location",
|
"name": "location",
|
||||||
"type": "text",
|
"type": "varchar",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"followers": {
|
"followers": {
|
||||||
"name": "followers",
|
"name": "followers",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false,
|
|
||||||
"default": 0
|
"default": 0
|
||||||
},
|
},
|
||||||
"following": {
|
"following": {
|
||||||
@ -253,23 +265,20 @@
|
|||||||
"type": "integer",
|
"type": "integer",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false,
|
|
||||||
"default": 0
|
"default": 0
|
||||||
},
|
},
|
||||||
"achievements": {
|
"achievements": {
|
||||||
"name": "achievements",
|
"name": "achievements",
|
||||||
"type": "text",
|
"type": "jsonb",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false,
|
||||||
"autoincrement": false,
|
"default": "'[]'::jsonb"
|
||||||
"default": "'[]'"
|
|
||||||
},
|
},
|
||||||
"points": {
|
"points": {
|
||||||
"name": "points",
|
"name": "points",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false,
|
|
||||||
"default": 0
|
"default": 0
|
||||||
},
|
},
|
||||||
"commits": {
|
"commits": {
|
||||||
@ -277,7 +286,6 @@
|
|||||||
"type": "integer",
|
"type": "integer",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false,
|
|
||||||
"default": 0
|
"default": 0
|
||||||
},
|
},
|
||||||
"line_of_codes": {
|
"line_of_codes": {
|
||||||
@ -285,67 +293,61 @@
|
|||||||
"type": "integer",
|
"type": "integer",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false,
|
|
||||||
"default": 0
|
"default": 0
|
||||||
},
|
},
|
||||||
"github_id": {
|
"github_id": {
|
||||||
"name": "github_id",
|
"name": "github_id",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"access_token": {
|
"access_token": {
|
||||||
"name": "access_token",
|
"name": "access_token",
|
||||||
"type": "text",
|
"type": "varchar",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": false,
|
"notNull": false
|
||||||
"autoincrement": false
|
|
||||||
},
|
},
|
||||||
"created_at": {
|
"created_at": {
|
||||||
"name": "created_at",
|
"name": "created_at",
|
||||||
"type": "text",
|
"type": "timestamp",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
"autoincrement": false,
|
|
||||||
"default": "CURRENT_TIMESTAMP"
|
"default": "CURRENT_TIMESTAMP"
|
||||||
},
|
},
|
||||||
"updated_at": {
|
"updated_at": {
|
||||||
"name": "updated_at",
|
"name": "updated_at",
|
||||||
"type": "text",
|
"type": "timestamp",
|
||||||
"primaryKey": false,
|
"primaryKey": false,
|
||||||
"notNull": true,
|
"notNull": true
|
||||||
"autoincrement": false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indexes": {
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {
|
||||||
"users_username_unique": {
|
"users_username_unique": {
|
||||||
"name": "users_username_unique",
|
"name": "users_username_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
"columns": [
|
"columns": [
|
||||||
"username"
|
"username"
|
||||||
],
|
]
|
||||||
"isUnique": true
|
|
||||||
},
|
},
|
||||||
"users_github_id_unique": {
|
"users_github_id_unique": {
|
||||||
"name": "users_github_id_unique",
|
"name": "users_github_id_unique",
|
||||||
|
"nullsNotDistinct": false,
|
||||||
"columns": [
|
"columns": [
|
||||||
"github_id"
|
"github_id"
|
||||||
],
|
]
|
||||||
"isUnique": true
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"foreignKeys": {},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"enums": {},
|
"enums": {},
|
||||||
|
"schemas": {},
|
||||||
|
"sequences": {},
|
||||||
"_meta": {
|
"_meta": {
|
||||||
|
"columns": {},
|
||||||
"schemas": {},
|
"schemas": {},
|
||||||
"tables": {},
|
"tables": {}
|
||||||
"columns": {}
|
|
||||||
},
|
|
||||||
"internal": {
|
|
||||||
"indexes": {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,9 +4,9 @@
|
|||||||
"entries": [
|
"entries": [
|
||||||
{
|
{
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"version": "6",
|
"version": "7",
|
||||||
"when": 1723211354217,
|
"when": 1723216591610,
|
||||||
"tag": "0000_tough_jubilee",
|
"tag": "0000_round_hellion",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
import { defineConfig } from "drizzle-kit";
|
import { defineConfig } from "drizzle-kit";
|
||||||
|
|
||||||
const DATABASE_PATH = process.env.DATABASE_PATH || "./data.db";
|
const DATABASE_PATH = process.env.DATABASE_PATH;
|
||||||
|
if (!DATABASE_PATH) {
|
||||||
|
throw new Error("DATABASE_PATH is not set");
|
||||||
|
}
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
schema: "./server/models/index.ts",
|
schema: "./server/models/index.ts",
|
||||||
out: "./server/db/migrations",
|
out: "./server/db/migrations",
|
||||||
dialect: "sqlite",
|
dialect: "postgresql",
|
||||||
dbCredentials: { url: DATABASE_PATH },
|
dbCredentials: { url: DATABASE_PATH },
|
||||||
verbose: true,
|
verbose: true,
|
||||||
});
|
});
|
||||||
|
@ -22,13 +22,15 @@ export const fetchRepoContributors = async (
|
|||||||
throw new Error("Repository not found!");
|
throw new Error("Repository not found!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!repo.userAccessToken) {
|
const accessToken =
|
||||||
|
repo.userAccessToken || import.meta.env.GITHUB_DEFAULT_TOKEN;
|
||||||
|
if (!accessToken) {
|
||||||
throw new Error("User access token not found!");
|
throw new Error("User access token not found!");
|
||||||
}
|
}
|
||||||
|
|
||||||
const contributors = await github.getRepoContributors(data.uri, {
|
const contributors = await github.getRepoContributors(data.uri, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${repo.userAccessToken}`,
|
Authorization: `Bearer ${accessToken}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -42,7 +44,11 @@ export const fetchRepoContributors = async (
|
|||||||
throw new Error("Cannot update repository!");
|
throw new Error("Cannot update repository!");
|
||||||
}
|
}
|
||||||
|
|
||||||
await queue.add("calculateUserPoints", { userId: result.userId });
|
await queue.add(
|
||||||
|
"calculateUserPoints",
|
||||||
|
{ userId: result.userId },
|
||||||
|
{ jobId: `calculateUserPoints:${result.userId}` }
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const onFetchRepoContribFailed = async (
|
export const onFetchRepoContribFailed = async (
|
||||||
|
@ -61,5 +61,9 @@ export const fetchRepoData = async (data: FetchRepoDataJobType) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await queue.add("calculateUserPoints", { userId: repository.userId });
|
await queue.add(
|
||||||
|
"calculateUserPoints",
|
||||||
|
{ userId: repository.userId },
|
||||||
|
{ jobId: `calculateUserPoints:${repository.userId}` }
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -27,5 +27,9 @@ export const fetchUserProfile = async (data: FetchUserProfileType) => {
|
|||||||
})
|
})
|
||||||
.where(eq(users.id, user.id));
|
.where(eq(users.id, user.id));
|
||||||
|
|
||||||
await queue.add("calculateUserPoints", { userId: user.id });
|
await queue.add(
|
||||||
|
"calculateUserPoints",
|
||||||
|
{ userId: user.id },
|
||||||
|
{ jobId: `calculateUserPoints:${user.id}` }
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -62,7 +62,7 @@ export const fetchUserRepos = async (data: FetchUserRepos) => {
|
|||||||
data,
|
data,
|
||||||
opts: {
|
opts: {
|
||||||
attempts: 5,
|
attempts: 5,
|
||||||
backoff: { type: "exponential", delay: 30000 },
|
backoff: { type: "exponential", delay: 3000 },
|
||||||
jobId: `contributors:${data.uri}`,
|
jobId: `contributors:${data.uri}`,
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
@ -32,7 +32,6 @@ const github = {
|
|||||||
|
|
||||||
const name = $(selectors.user.name).text().trim();
|
const name = $(selectors.user.name).text().trim();
|
||||||
const avatar = $(selectors.user.avatar).attr("src");
|
const avatar = $(selectors.user.avatar).attr("src");
|
||||||
console.log({ avatar });
|
|
||||||
const location = $(selectors.user.location).text().trim();
|
const location = $(selectors.user.location).text().trim();
|
||||||
const followers = intval($(selectors.user.followers).text().trim());
|
const followers = intval($(selectors.user.followers).text().trim());
|
||||||
const following = intval($(selectors.user.following).text().trim());
|
const following = intval($(selectors.user.following).text().trim());
|
||||||
|
@ -1,23 +1,24 @@
|
|||||||
import { InferInsertModel, InferSelectModel, relations } from "drizzle-orm";
|
import { InferInsertModel, InferSelectModel, relations } from "drizzle-orm";
|
||||||
import {
|
import {
|
||||||
text,
|
varchar,
|
||||||
sqliteTable,
|
serial,
|
||||||
|
pgTable,
|
||||||
integer,
|
integer,
|
||||||
index,
|
index,
|
||||||
real,
|
doublePrecision,
|
||||||
} from "drizzle-orm/sqlite-core";
|
} from "drizzle-orm/pg-core";
|
||||||
import { repositories } from "./repositories";
|
import { repositories } from "./repositories";
|
||||||
|
|
||||||
export const repoLanguages = sqliteTable(
|
export const repoLanguages = pgTable(
|
||||||
"repository_languages",
|
"repository_languages",
|
||||||
{
|
{
|
||||||
id: integer("id").primaryKey({ autoIncrement: true }),
|
id: serial("id").primaryKey(),
|
||||||
repoId: integer("repo_id")
|
repoId: integer("repo_id")
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => repositories.id),
|
.references(() => repositories.id),
|
||||||
|
|
||||||
name: text("name").notNull(),
|
name: varchar("name").notNull(),
|
||||||
percentage: real("percentage").notNull(),
|
percentage: doublePrecision("percentage").notNull(),
|
||||||
},
|
},
|
||||||
(t) => ({
|
(t) => ({
|
||||||
nameIdx: index("repository_languages_name_idx").on(t.name),
|
nameIdx: index("repository_languages_name_idx").on(t.name),
|
||||||
|
@ -5,37 +5,44 @@ import {
|
|||||||
relations,
|
relations,
|
||||||
sql,
|
sql,
|
||||||
} from "drizzle-orm";
|
} from "drizzle-orm";
|
||||||
import { text, sqliteTable, integer, index } from "drizzle-orm/sqlite-core";
|
import {
|
||||||
|
varchar,
|
||||||
|
pgTable,
|
||||||
|
integer,
|
||||||
|
index,
|
||||||
|
serial,
|
||||||
|
jsonb,
|
||||||
|
boolean,
|
||||||
|
timestamp,
|
||||||
|
} from "drizzle-orm/pg-core";
|
||||||
import { users } from "./users";
|
import { users } from "./users";
|
||||||
import { repoLanguages } from "./repo-languages";
|
import { repoLanguages } from "./repo-languages";
|
||||||
|
|
||||||
export const repositories = sqliteTable(
|
export const repositories = pgTable(
|
||||||
"repositories",
|
"repositories",
|
||||||
{
|
{
|
||||||
id: integer("id").primaryKey({ autoIncrement: true }),
|
id: serial("id").primaryKey(),
|
||||||
userId: integer("user_id")
|
userId: integer("user_id")
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => users.id),
|
.references(() => users.id),
|
||||||
|
|
||||||
name: text("name").notNull(),
|
name: varchar("name").notNull(),
|
||||||
uri: text("uri").notNull(),
|
uri: varchar("uri").notNull(),
|
||||||
language: text("language").notNull(),
|
language: varchar("language").notNull(),
|
||||||
stars: integer("stars").notNull(),
|
stars: integer("stars").notNull(),
|
||||||
forks: integer("forks").notNull(),
|
forks: integer("forks").notNull(),
|
||||||
lastUpdate: text("last_update").notNull(),
|
lastUpdate: varchar("last_update").notNull(),
|
||||||
contributors: text("contributors", { mode: "json" }).$type<Contributor[]>(),
|
contributors: jsonb("contributors").$type<Contributor[]>(),
|
||||||
|
|
||||||
isPending: integer("is_pending", { mode: "boolean" })
|
isPending: boolean("is_pending").notNull().default(false),
|
||||||
.notNull()
|
isError: boolean("is_error").notNull().default(false),
|
||||||
.default(false),
|
|
||||||
isError: integer("is_error", { mode: "boolean" }).notNull().default(false),
|
|
||||||
|
|
||||||
createdAt: text("created_at")
|
createdAt: timestamp("created_at")
|
||||||
.notNull()
|
.notNull()
|
||||||
.default(sql`CURRENT_TIMESTAMP`),
|
.default(sql`CURRENT_TIMESTAMP`),
|
||||||
updatedAt: text("updated_at")
|
updatedAt: timestamp("updated_at")
|
||||||
.notNull()
|
.notNull()
|
||||||
.$onUpdate(() => sql`CURRENT_TIMESTAMP`),
|
.$onUpdate(() => new Date()),
|
||||||
},
|
},
|
||||||
(t) => ({
|
(t) => ({
|
||||||
nameIdx: index("repositories_name_idx").on(t.name),
|
nameIdx: index("repositories_name_idx").on(t.name),
|
||||||
|
@ -1,30 +1,35 @@
|
|||||||
import { Achievement } from "@server/lib/github";
|
import { Achievement } from "@server/lib/github";
|
||||||
import { InferInsertModel, InferSelectModel, sql } from "drizzle-orm";
|
import { InferInsertModel, InferSelectModel, sql } from "drizzle-orm";
|
||||||
import { text, sqliteTable, integer } from "drizzle-orm/sqlite-core";
|
import {
|
||||||
|
varchar,
|
||||||
|
pgTable,
|
||||||
|
serial,
|
||||||
|
integer,
|
||||||
|
jsonb,
|
||||||
|
timestamp,
|
||||||
|
} from "drizzle-orm/pg-core";
|
||||||
|
|
||||||
export const users = sqliteTable("users", {
|
export const users = pgTable("users", {
|
||||||
id: integer("id").primaryKey({ autoIncrement: true }),
|
id: serial("id").primaryKey(),
|
||||||
username: text("username").notNull().unique(),
|
username: varchar("username").notNull().unique(),
|
||||||
name: text("name").notNull(),
|
name: varchar("name").notNull(),
|
||||||
avatar: text("avatar"),
|
avatar: varchar("avatar"),
|
||||||
location: text("location"),
|
location: varchar("location"),
|
||||||
followers: integer("followers").notNull().default(0),
|
followers: integer("followers").notNull().default(0),
|
||||||
following: integer("following").notNull().default(0),
|
following: integer("following").notNull().default(0),
|
||||||
achievements: text("achievements", { mode: "json" })
|
achievements: jsonb("achievements").$type<Achievement[]>().default([]),
|
||||||
.$type<Achievement[]>()
|
|
||||||
.default([]),
|
|
||||||
points: integer("points").notNull().default(0),
|
points: integer("points").notNull().default(0),
|
||||||
commits: integer("commits").notNull().default(0),
|
commits: integer("commits").notNull().default(0),
|
||||||
lineOfCodes: integer("line_of_codes").notNull().default(0),
|
lineOfCodes: integer("line_of_codes").notNull().default(0),
|
||||||
githubId: integer("github_id").unique(),
|
githubId: integer("github_id").unique(),
|
||||||
accessToken: text("access_token"),
|
accessToken: varchar("access_token"),
|
||||||
|
|
||||||
createdAt: text("created_at")
|
createdAt: timestamp("created_at")
|
||||||
.notNull()
|
.notNull()
|
||||||
.default(sql`CURRENT_TIMESTAMP`),
|
.default(sql`CURRENT_TIMESTAMP`),
|
||||||
updatedAt: text("updated_at")
|
updatedAt: timestamp("updated_at")
|
||||||
.notNull()
|
.notNull()
|
||||||
.$onUpdate(() => sql`CURRENT_TIMESTAMP`),
|
.$onUpdate(() => new Date()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type User = InferSelectModel<typeof users>;
|
export type User = InferSelectModel<typeof users>;
|
||||||
|
@ -59,7 +59,8 @@ export class LeaderboardRepository {
|
|||||||
.from(repositories)
|
.from(repositories)
|
||||||
.innerJoin(repoLanguages, eq(repoLanguages.repoId, repositories.id))
|
.innerJoin(repoLanguages, eq(repoLanguages.repoId, repositories.id))
|
||||||
.groupBy(repoLanguages.name)
|
.groupBy(repoLanguages.name)
|
||||||
.orderBy(desc(sql`count(*) * avg(${repoLanguages.percentage})`));
|
.orderBy(desc(sql`count(*) * avg(${repoLanguages.percentage})`))
|
||||||
|
.limit(20);
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
@ -116,7 +117,8 @@ export class LeaderboardRepository {
|
|||||||
.innerJoin(repoLanguages, eq(repoLanguages.repoId, repositories.id))
|
.innerJoin(repoLanguages, eq(repoLanguages.repoId, repositories.id))
|
||||||
.where(inArray(sql`lower(${repoLanguages.name})`, languages))
|
.where(inArray(sql`lower(${repoLanguages.name})`, languages))
|
||||||
.groupBy(users.id)
|
.groupBy(users.id)
|
||||||
.orderBy(desc(count()));
|
.orderBy(desc(count()))
|
||||||
|
.limit(100);
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user