Skip to content
This repository was archived by the owner on Jan 22, 2024. It is now read-only.

Commit a7008c8

Browse files
authored
Manual DB Seed (#2)
* add newest ts-node version which solves extension issues * init docs * modify migrate statement * [ADD] add db diagram and manual seed for lang,dict, and entries (work in progress * [ADD] add etyomolgy manual load * [ADD] finish adding entries/ety/usages/groups/defitions with manual DB actions * add functionality for multiple files in dir and change raw sql to prisma create * rm console logs * remove drawio file
1 parent 2c24503 commit a7008c8

File tree

1 file changed

+215
-0
lines changed

1 file changed

+215
-0
lines changed

prisma/manualSeed.ts

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
import prisma, {
2+
Definition,
3+
Dictionary,
4+
Entry,
5+
Etymology,
6+
Group,
7+
Language,
8+
Usage
9+
} from '@prisma/client';
10+
const { Prisma } = prisma;
11+
import type { Dictionary as XmlDictionary } from './types';
12+
import { fileURLToPath } from 'url';
13+
import { join, dirname } from 'path';
14+
import { readFileSync, readdirSync } from 'fs';
15+
import { compact, isArray } from 'lodash-es';
16+
import xml from 'fast-xml-parser';
17+
import he from 'he';
18+
19+
const prismaClient = new prisma.PrismaClient({
20+
log: ['query', 'info', 'warn', 'error']
21+
});
22+
23+
const dictionaryDir: string = join(dirname(fileURLToPath(import.meta.url)), 'dictionaries');
24+
const files: string[] = readdirSync(dictionaryDir.toString());
25+
const convertToArray = <T>(value: T | T[]): T[] => {
26+
if (!value) return [];
27+
return compact(isArray(value) ? value : [value]);
28+
};
29+
30+
async function main() {
31+
// note: template variables can only be used for data values.
32+
console.log('🌱 seeding the db!!!!!!!!');
33+
34+
for (let file of files) {
35+
if (file === '.DS_Store') {
36+
continue;
37+
}
38+
39+
const { dictionary } = xml.parse(readFileSync(join(dictionaryDir, file), 'utf8'), {
40+
attributeNamePrefix: '',
41+
ignoreAttributes: false,
42+
attrValueProcessor: (val) => he.decode(val, { isAttributeValue: true }),
43+
tagValueProcessor: (val) => he.decode(val)
44+
}) as { dictionary: XmlDictionary };
45+
46+
// get dict source/target lang codes from filename
47+
const splitFilename: string[] = file.split('-');
48+
const sourceCode = splitFilename[0];
49+
const targetCode = splitFilename[1].slice(0, -4);
50+
51+
/* steps:
52+
- get ids from language table
53+
- check dictionaries if source/target dict exists already
54+
- if exists, stop/return
55+
- check if we can add source/target lang to languages
56+
- add if necessary
57+
- requery to grab language ids
58+
- create dictionary
59+
- create entries
60+
- create etymologies
61+
- create usages
62+
- create groups (if any)
63+
- create definitions
64+
*/
65+
66+
// get ids from language table
67+
let dbSourceLang: Language | null = await prismaClient.language.findFirst({
68+
where: {
69+
code: sourceCode
70+
}
71+
});
72+
let dbTargetLang: Language | null = await prismaClient.language.findFirst({
73+
where: {
74+
code: targetCode
75+
}
76+
});
77+
78+
// check dictionaries if source/target dict exists already
79+
if (dbSourceLang != null && dbTargetLang != null) {
80+
const dict: Dictionary | null = await prismaClient.dictionary.findFirst({
81+
where: {
82+
AND: [
83+
{
84+
sourceLanguageID: dbSourceLang.id,
85+
targetLanguageID: dbTargetLang.id
86+
}
87+
]
88+
}
89+
});
90+
91+
// if exists, stop/return
92+
if (dict != null) {
93+
return;
94+
}
95+
}
96+
97+
// if source/target language don't exist, add them to the db
98+
if (dbSourceLang == null) {
99+
await prismaClient.language.create({
100+
data: {
101+
code: sourceCode,
102+
flag: sourceCode
103+
}
104+
});
105+
}
106+
if (dbTargetLang == null) {
107+
await prismaClient.language.create({
108+
data: {
109+
code: targetCode,
110+
flag: targetCode
111+
}
112+
});
113+
}
114+
115+
// requery for language ids
116+
dbSourceLang = await prismaClient.language.findFirst({
117+
where: {
118+
code: sourceCode
119+
}
120+
});
121+
dbTargetLang = await prismaClient.language.findFirst({
122+
where: {
123+
code: targetCode
124+
}
125+
});
126+
127+
// create dictionary
128+
const dbDict: Dictionary = await prismaClient.dictionary.create({
129+
data: {
130+
name: dictionary.name,
131+
sourceLanguageID: dbSourceLang!.id,
132+
targetLanguageID: dbTargetLang!.id
133+
}
134+
});
135+
136+
// here after creating, we get the ID back from the DB
137+
// and we use that ID to set the FKs of the children
138+
// create entries
139+
const xmlEntries = convertToArray(dictionary.entry);
140+
for (let i = 0; i < xmlEntries.length; i++) {
141+
const dbEntry: Entry = await prismaClient.entry.create({
142+
data: {
143+
term: xmlEntries[i].term,
144+
dictionaryID: dbDict.id
145+
}
146+
});
147+
// create etymologies
148+
const xmlEtyomologies = convertToArray(xmlEntries[i]?.ety);
149+
for (let j = 0; j < xmlEtyomologies.length; j++) {
150+
const dbEty: Etymology = await prismaClient.etymology.create({
151+
data: {
152+
description: xmlEntries[i].term,
153+
entryID: dbEntry.id
154+
}
155+
});
156+
157+
// create usages
158+
const xmlUsages = convertToArray(xmlEtyomologies[j]?.usage);
159+
for (let k = 0; k < xmlUsages.length; k++) {
160+
const dbUsage: Usage = await prismaClient.usage.create({
161+
data: {
162+
pos: xmlUsages[k]!.pos,
163+
etymologyID: dbEty.id
164+
}
165+
});
166+
167+
// create groups
168+
const xmlGroups = convertToArray(xmlUsages[k]?.group);
169+
for (let l = 0; l < xmlGroups.length; l++) {
170+
const dbGroup: Group = await prismaClient.group.create({
171+
data: {
172+
description: xmlGroups[l]!.description,
173+
usageID: dbUsage.id
174+
}
175+
});
176+
177+
// create grouped definitions
178+
const xmlDefinitionsGroup = convertToArray(xmlGroups[l]?.definition);
179+
for (const m of xmlDefinitionsGroup) {
180+
const dbDefinition: Definition = await prismaClient.definition.create({
181+
data: {
182+
text: m!,
183+
usageID: dbUsage.id,
184+
groupID: dbGroup.id
185+
}
186+
});
187+
}
188+
}
189+
190+
// create definitions without groups
191+
const xmlDefinitionsNoGroup = convertToArray(xmlUsages[k]?.definition);
192+
for (const n of xmlDefinitionsNoGroup) {
193+
const dbDefinition: Definition = await prismaClient.definition.create({
194+
data: {
195+
text: n!,
196+
usageID: dbUsage.id,
197+
groupID: null
198+
}
199+
});
200+
}
201+
}
202+
}
203+
}
204+
}
205+
}
206+
207+
main()
208+
.catch((e) => {
209+
console.error(e);
210+
process.exit(1);
211+
})
212+
.finally(async () => {
213+
// Exit from db session
214+
await prismaClient.$disconnect();
215+
});

0 commit comments

Comments
 (0)