diff --git a/media-store/app/src/App.test.js b/media-store/app/src/App.test.js deleted file mode 100644 index 4db7ebc2..00000000 --- a/media-store/app/src/App.test.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -import { render } from '@testing-library/react'; -import App from './App'; - -test('renders learn react link', () => { - const { getByText } = render(); - const linkElement = getByText(/learn react/i); - expect(linkElement).toBeInTheDocument(); -}); diff --git a/media-store/app/src/pages/InvoicePage.js b/media-store/app/src/pages/InvoicePage.js index b63efce1..a4644e97 100644 --- a/media-store/app/src/pages/InvoicePage.js +++ b/media-store/app/src/pages/InvoicePage.js @@ -30,8 +30,8 @@ const InvoicePage = () => { const { handleError } = useErrors(); const { user, invoicedItems, setInvoicedItems, setLoading } = useAppState(); - const data = invoicedItems.map(({ ID: key, ...otherProps }) => ({ - key, + const data = invoicedItems.map(({ ID, ...otherProps }) => ({ + key: `invoiceItem${ID}`, ...otherProps, })); diff --git a/media-store/package.json b/media-store/package.json index 67157eef..1bc56dea 100644 --- a/media-store/package.json +++ b/media-store/package.json @@ -23,7 +23,7 @@ "scripts": { "start": "npx cds run", "deploy": "cds deploy --to sqlite:mychinook.db", - "test": "mocha test/media-service.test.js --verbose --timeout 10000" + "test": "mocha test/media-store.test.js --verbose --timeout 10000" }, "cds": { "ACCESS_TOKEN_SECRET": "secret", @@ -41,4 +41,4 @@ } } } -} \ No newline at end of file +} diff --git a/media-store/srv/user-service.cds b/media-store/srv/user-service.cds index 08157e8b..8ffde3db 100644 --- a/media-store/srv/user-service.cds +++ b/media-store/srv/user-service.cds @@ -24,14 +24,7 @@ service Users { }; action login(email : String(111), password : String(200)) returns AuthData; - - action refreshTokens(refreshToken : String(500)) returns { - accessToken : String(500); - refreshToken : String(500); - ID : Integer; - email : String(500); - roles : array of String(111); - }; + action refreshTokens(refreshToken : String(500)) returns AuthData; } annotate Users.Customers with @(restrict : [{ diff --git a/media-store/srv/user-service.js b/media-store/srv/user-service.js index eb305111..02e62be9 100644 --- a/media-store/srv/user-service.js +++ b/media-store/srv/user-service.js @@ -3,8 +3,8 @@ const jwt = require("jsonwebtoken"); const bcrypt = require("bcryptjs"); const { ACCESS_TOKEN_SECRET, REFRESH_TOKEN_SECRET } = cds.env; -const ACCESS_TOKEN_EXP_IN = "10m"; -const REFRESH_TOKEN_EXPIRES_IN = "20m"; +const ACCESS_TOKEN_EXP_IN = "10s"; +const REFRESH_TOKEN_EXPIRES_IN = "15s"; const comparePasswords = async (password, hashedPassword) => { return new Promise((resolve, reject) => diff --git a/media-store/test/data/media-service.mock.js b/media-store/test/data/media-service.mock.js deleted file mode 100644 index 11957e5a..00000000 --- a/media-store/test/data/media-service.mock.js +++ /dev/null @@ -1,369 +0,0 @@ -const FIRST_EMPLOYEE = { - "@odata.context": "$metadata#Employees/$entity", - ID: 1, - lastName: "Adams", - firstName: "Andrew", - city: "Edmonton", - state: "AB", - address: "11120 Jasper Ave NW", - country: "Canada", - postalCode: "T5K 2N1", - phone: "+1 (780) 428-9482", - fax: "+1 (780) 428-3457", - email: "andrew@chinookcorp.com", - title: "General Manager", - birthDate: "1962-02-17T21:00:00Z", - hireDate: "2002-08-13T21:00:00Z", - reportsTo_ID: null, -}; - -const SECOND_EMPLOYEE_WITH_EXPANDED_FIELDS = { - "@odata.context": "$metadata#Employees(subordinates(),reportsTo())/$entity", - ID: 2, - lastName: "Edwards", - firstName: "Nancy", - city: "Calgary", - state: "AB", - address: "825 8 Ave SW", - country: "Canada", - postalCode: "T2P 2T3", - phone: "+1 (403) 262-3443", - fax: "+1 (403) 262-3322", - email: "nancy@chinookcorp.com", - title: "Sales Manager", - birthDate: "1958-12-07T21:00:00Z", - hireDate: "2002-04-30T21:00:00Z", - reportsTo_ID: 1, - reportsTo: { - ID: 1, - lastName: "Adams", - firstName: "Andrew", - city: "Edmonton", - state: "AB", - address: "11120 Jasper Ave NW", - country: "Canada", - postalCode: "T5K 2N1", - phone: "+1 (780) 428-9482", - fax: "+1 (780) 428-3457", - email: "andrew@chinookcorp.com", - title: "General Manager", - birthDate: "1962-02-17T21:00:00Z", - hireDate: "2002-08-13T21:00:00Z", - reportsTo_ID: null, - }, - subordinates: [ - { - ID: 3, - lastName: "Peacock", - firstName: "Jane", - city: "Calgary", - state: "AB", - address: "1111 6 Ave SW", - country: "Canada", - postalCode: "T2P 5M5", - phone: "+1 (403) 262-3443", - fax: "+1 (403) 262-6712", - email: "jane@chinookcorp.com", - title: "Sales Support Agent", - birthDate: "1973-08-28T21:00:00Z", - hireDate: "2002-03-31T21:00:00Z", - reportsTo_ID: 2, - }, - { - ID: 4, - lastName: "Park", - firstName: "Margaret", - city: "Calgary", - state: "AB", - address: "683 10 Street SW", - country: "Canada", - postalCode: "T2P 5G3", - phone: "+1 (403) 263-4423", - fax: "+1 (403) 263-4289", - email: "margaret@chinookcorp.com", - title: "Sales Support Agent", - birthDate: "1947-09-18T21:00:00Z", - hireDate: "2003-05-02T21:00:00Z", - reportsTo_ID: 2, - }, - { - ID: 5, - lastName: "Johnson", - firstName: "Steve", - city: "Calgary", - state: "AB", - address: "7727B 41 Ave", - country: "Canada", - postalCode: "T3B 1Y7", - phone: "1 (780) 836-9987", - fax: "1 (780) 836-9543", - email: "steve@chinookcorp.com", - title: "Sales Support Agent", - birthDate: "1965-03-02T21:00:00Z", - hireDate: "2003-10-16T21:00:00Z", - reportsTo_ID: 2, - }, - ], -}; - -const ALL_ALBUMS_WITH_TRACKS_BY_ARTIST = { - "@odata.context": "$metadata#Albums(tracks())", - value: [ - { - ID: 1, - title: "For Those About To Rock We Salute You", - artist_ID: 1, - tracks: [ - { - ID: 1, - name: "For Those About To Rock (We Salute You)", - composer: "Angus Young, Malcolm Young, Brian Johnson", - milliseconds: 343719, - bytes: 11170334, - unitPrice: 0.99, - album_ID: 1, - mediaType_ID: 1, - genre_ID: 1, - }, - { - ID: 6, - name: "Put The Finger On You", - composer: "Angus Young, Malcolm Young, Brian Johnson", - milliseconds: 205662, - bytes: 6713451, - unitPrice: 0.99, - album_ID: 1, - mediaType_ID: 1, - genre_ID: 1, - }, - { - ID: 7, - name: "Let's Get It Up", - composer: "Angus Young, Malcolm Young, Brian Johnson", - milliseconds: 233926, - bytes: 7636561, - unitPrice: 0.99, - album_ID: 1, - mediaType_ID: 1, - genre_ID: 1, - }, - { - ID: 8, - name: "Inject The Venom", - composer: "Angus Young, Malcolm Young, Brian Johnson", - milliseconds: 210834, - bytes: 6852860, - unitPrice: 0.99, - album_ID: 1, - mediaType_ID: 1, - genre_ID: 1, - }, - { - ID: 9, - name: "Snowballed", - composer: "Angus Young, Malcolm Young, Brian Johnson", - milliseconds: 203102, - bytes: 6599424, - unitPrice: 0.99, - album_ID: 1, - mediaType_ID: 1, - genre_ID: 1, - }, - { - ID: 10, - name: "Evil Walks", - composer: "Angus Young, Malcolm Young, Brian Johnson", - milliseconds: 263497, - bytes: 8611245, - unitPrice: 0.99, - album_ID: 1, - mediaType_ID: 1, - genre_ID: 1, - }, - { - ID: 11, - name: "C.O.D.", - composer: "Angus Young, Malcolm Young, Brian Johnson", - milliseconds: 199836, - bytes: 6566314, - unitPrice: 0.99, - album_ID: 1, - mediaType_ID: 1, - genre_ID: 1, - }, - { - ID: 12, - name: "Breaking The Rules", - composer: "Angus Young, Malcolm Young, Brian Johnson", - milliseconds: 263288, - bytes: 8596840, - unitPrice: 0.99, - album_ID: 1, - mediaType_ID: 1, - genre_ID: 1, - }, - { - ID: 13, - name: "Night Of The Long Knives", - composer: "Angus Young, Malcolm Young, Brian Johnson", - milliseconds: 205688, - bytes: 6706347, - unitPrice: 0.99, - album_ID: 1, - mediaType_ID: 1, - genre_ID: 1, - }, - { - ID: 14, - name: "Spellbound", - composer: "Angus Young, Malcolm Young, Brian Johnson", - milliseconds: 270863, - bytes: 8817038, - unitPrice: 0.99, - album_ID: 1, - mediaType_ID: 1, - genre_ID: 1, - }, - ], - }, - { - ID: 4, - title: "Let There Be Rock", - artist_ID: 1, - tracks: [ - { - ID: 15, - name: "Go Down", - composer: "AC/DC", - milliseconds: 331180, - bytes: 10847611, - unitPrice: 0.99, - album_ID: 4, - mediaType_ID: 1, - genre_ID: 1, - }, - { - ID: 16, - name: "Dog Eat Dog", - composer: "AC/DC", - milliseconds: 215196, - bytes: 7032162, - unitPrice: 0.99, - album_ID: 4, - mediaType_ID: 1, - genre_ID: 1, - }, - { - ID: 17, - name: "Let There Be Rock", - composer: "AC/DC", - milliseconds: 366654, - bytes: 12021261, - unitPrice: 0.99, - album_ID: 4, - mediaType_ID: 1, - genre_ID: 1, - }, - { - ID: 18, - name: "Bad Boy Boogie", - composer: "AC/DC", - milliseconds: 267728, - bytes: 8776140, - unitPrice: 0.99, - album_ID: 4, - mediaType_ID: 1, - genre_ID: 1, - }, - { - ID: 19, - name: "Problem Child", - composer: "AC/DC", - milliseconds: 325041, - bytes: 10617116, - unitPrice: 0.99, - album_ID: 4, - mediaType_ID: 1, - genre_ID: 1, - }, - { - ID: 20, - name: "Overdose", - composer: "AC/DC", - milliseconds: 369319, - bytes: 12066294, - unitPrice: 0.99, - album_ID: 4, - mediaType_ID: 1, - genre_ID: 1, - }, - { - ID: 21, - name: "Hell Ain't A Bad Place To Be", - composer: "AC/DC", - milliseconds: 254380, - bytes: 8331286, - unitPrice: 0.99, - album_ID: 4, - mediaType_ID: 1, - genre_ID: 1, - }, - { - ID: 22, - name: "Whole Lotta Rosie", - composer: "AC/DC", - milliseconds: 323761, - bytes: 10547154, - unitPrice: 0.99, - album_ID: 4, - mediaType_ID: 1, - genre_ID: 1, - }, - ], - }, - ], -}; - -const CUSTOMER_WITH_THEIR_SUPPORT_REP = { - "@odata.context": "$metadata#Customers(supportRep())/$entity", - ID: 1, - lastName: "Gonçalves", - firstName: "Luís", - city: "São José dos Campos", - state: "SP", - address: "Av. Brigadeiro Faria Lima, 2170", - country: "Brazil", - postalCode: "12227-000", - phone: "+55 (12) 3923-5555", - fax: "+55 (12) 3923-5566", - email: "luisg@embraer.com.br", - company: "Embraer - Empresa Brasileira de Aeronáutica S.A.", - supportRep_ID: 3, - supportRep: { - ID: 3, - lastName: "Peacock", - firstName: "Jane", - city: "Calgary", - state: "AB", - address: "1111 6 Ave SW", - country: "Canada", - postalCode: "T2P 5M5", - phone: "+1 (403) 262-3443", - fax: "+1 (403) 262-6712", - email: "jane@chinookcorp.com", - title: "Sales Support Agent", - birthDate: "1973-08-28T21:00:00Z", - hireDate: "2002-03-31T21:00:00Z", - reportsTo_ID: 2, - }, -}; - -const EIGHTH_ALBUM_TRACKS_COUNT = 3290; - -module.exports = { - FIRST_EMPLOYEE, - SECOND_EMPLOYEE_WITH_EXPANDED_FIELDS, - ALL_ALBUMS_WITH_TRACKS_BY_ARTIST, - CUSTOMER_WITH_THEIR_SUPPORT_REP, - EIGHTH_ALBUM_TRACKS_COUNT, -}; diff --git a/media-store/test/data/media-store.mock.js b/media-store/test/data/media-store.mock.js new file mode 100644 index 00000000..03f1837a --- /dev/null +++ b/media-store/test/data/media-store.mock.js @@ -0,0 +1,188 @@ +const FIRST_TRACK = { + "@odata.context": "$metadata#Tracks(genre(),album(artist()))/$entity", + ID: 1, + name: "For Those About To Rock (We Salute You)", + composer: "Angus Young, Malcolm Young, Brian Johnson", + unitPrice: 0.99, + album_ID: 1, + genre_ID: 1, + album: { + ID: 1, + title: "For Those About To Rock We Salute You", + artist_ID: 1, + artist: { + ID: 1, + name: "AC/DC", + }, + }, + genre: { + ID: 1, + name: "Rock", + }, +}; + +const ALL_ALBUMS_WITH_TRACKS_BY_ARTIST = { + "@odata.context": "$metadata#Albums(tracks())", + value: [ + { + ID: 1, + title: "For Those About To Rock We Salute You", + artist_ID: 1, + tracks: [ + { + ID: 1, + name: "For Those About To Rock (We Salute You)", + composer: "Angus Young, Malcolm Young, Brian Johnson", + unitPrice: 0.99, + album_ID: 1, + genre_ID: 1, + }, + { + ID: 6, + name: "Put The Finger On You", + composer: "Angus Young, Malcolm Young, Brian Johnson", + unitPrice: 0.99, + album_ID: 1, + genre_ID: 1, + }, + { + ID: 7, + name: "Let's Get It Up", + composer: "Angus Young, Malcolm Young, Brian Johnson", + unitPrice: 0.99, + album_ID: 1, + genre_ID: 1, + }, + { + ID: 8, + name: "Inject The Venom", + composer: "Angus Young, Malcolm Young, Brian Johnson", + unitPrice: 0.99, + album_ID: 1, + genre_ID: 1, + }, + { + ID: 9, + name: "Snowballed", + composer: "Angus Young, Malcolm Young, Brian Johnson", + unitPrice: 0.99, + album_ID: 1, + genre_ID: 1, + }, + { + ID: 10, + name: "Evil Walks", + composer: "Angus Young, Malcolm Young, Brian Johnson", + unitPrice: 0.99, + album_ID: 1, + genre_ID: 1, + }, + { + ID: 11, + name: "C.O.D.", + composer: "Angus Young, Malcolm Young, Brian Johnson", + unitPrice: 0.99, + album_ID: 1, + genre_ID: 1, + }, + { + ID: 12, + name: "Breaking The Rules", + composer: "Angus Young, Malcolm Young, Brian Johnson", + unitPrice: 0.99, + album_ID: 1, + genre_ID: 1, + }, + { + ID: 13, + name: "Night Of The Long Knives", + composer: "Angus Young, Malcolm Young, Brian Johnson", + unitPrice: 0.99, + album_ID: 1, + genre_ID: 1, + }, + { + ID: 14, + name: "Spellbound", + composer: "Angus Young, Malcolm Young, Brian Johnson", + unitPrice: 0.99, + album_ID: 1, + genre_ID: 1, + }, + ], + }, + { + ID: 4, + title: "Let There Be Rock", + artist_ID: 1, + tracks: [ + { + ID: 15, + name: "Go Down", + composer: "AC/DC", + unitPrice: 0.99, + album_ID: 4, + genre_ID: 1, + }, + { + ID: 16, + name: "Dog Eat Dog", + composer: "AC/DC", + unitPrice: 0.99, + album_ID: 4, + genre_ID: 1, + }, + { + ID: 17, + name: "Let There Be Rock", + composer: "AC/DC", + unitPrice: 0.99, + album_ID: 4, + genre_ID: 1, + }, + { + ID: 18, + name: "Bad Boy Boogie", + composer: "AC/DC", + unitPrice: 0.99, + album_ID: 4, + genre_ID: 1, + }, + { + ID: 19, + name: "Problem Child", + composer: "AC/DC", + unitPrice: 0.99, + album_ID: 4, + genre_ID: 1, + }, + { + ID: 20, + name: "Overdose", + composer: "AC/DC", + unitPrice: 0.99, + album_ID: 4, + genre_ID: 1, + }, + { + ID: 21, + name: "Hell Ain't A Bad Place To Be", + composer: "AC/DC", + unitPrice: 0.99, + album_ID: 4, + genre_ID: 1, + }, + { + ID: 22, + name: "Whole Lotta Rosie", + composer: "AC/DC", + unitPrice: 0.99, + album_ID: 4, + genre_ID: 1, + }, + ], + }, + ], +}; + +module.exports = { FIRST_TRACK, ALL_ALBUMS_WITH_TRACKS_BY_ARTIST }; diff --git a/media-store/test/media-service.test.js b/media-store/test/media-service.test.js deleted file mode 100644 index e9a0432d..00000000 --- a/media-store/test/media-service.test.js +++ /dev/null @@ -1,67 +0,0 @@ -const cds = require("../../test/cds"); -const { GET, expect } = cds.test("media-store").in(__dirname, "../../"); - -const { - FIRST_EMPLOYEE, - SECOND_EMPLOYEE_WITH_EXPANDED_FIELDS, - ALL_ALBUMS_WITH_TRACKS_BY_ARTIST, - CUSTOMER_WITH_THEIR_SUPPORT_REP, - EIGHTH_ALBUM_TRACKS_COUNT, -} = require("./data/media-service.mock"); - -describe("Media service", () => { - it("should bootstrap the services successfully", () => { - const { MediaService, db } = cds.services; - const { Employees } = MediaService.entities; - - expect(MediaService).not.to.be.undefined; - expect(db).not.to.be.undefined; - expect(Employees).not.to.be.undefined; - }); - - describe("Employees", () => { - it("should return employee (ID=1)", async () => { - const { data } = await GET("/media/Employees(1)"); - expect(data).to.eql(FIRST_EMPLOYEE); - }); - - it("should return employee (ID=2) with subordinates and whom he reports to", async () => { - const { data } = await GET( - `/media/Employees(2)?$expand=subordinates,reportsTo` - ); - expect(data).to.eql(SECOND_EMPLOYEE_WITH_EXPANDED_FIELDS); - }); - }); - - describe("Albums", () => { - it("should return all albums with tracks by artist", async () => { - const { data } = await GET( - `/media/Albums?$filter=artist_ID eq 1&$expand=tracks` - ); - expect(data).to.eql(ALL_ALBUMS_WITH_TRACKS_BY_ARTIST); - }); - }); - - describe("Customers", () => { - it("should return customer with their invoices", async () => { - const { data } = await GET(`/media/Customers(1)?$expand=supportRep`); - expect(data).to.eql(CUSTOMER_WITH_THEIR_SUPPORT_REP); - }); - }); - - describe("Playlists", () => { - it("should return playlist with their tracks", async () => { - const { data } = await GET(`/media/Customers(1)?$expand=supportRep`); - expect(data).to.eql(CUSTOMER_WITH_THEIR_SUPPORT_REP); - }); - }); - - describe("Tracks", () => { - it("should return the number of tracks by album", async () => { - const { data } = await GET( - `/media/PlaylistTrack/$count?$filter=playlist_ID eq 8` - ); - expect(data).to.eql(EIGHTH_ALBUM_TRACKS_COUNT); - }); - }); -}); diff --git a/media-store/test/media-store.test.js b/media-store/test/media-store.test.js new file mode 100644 index 00000000..82b4b2a1 --- /dev/null +++ b/media-store/test/media-store.test.js @@ -0,0 +1,46 @@ +const { GET, POST, expect } = require("../../test").run("media-store"); +const cds = require("@sap/cds/lib"); + +class MockedUser extends cds.User { + constructor(attr, roles, id) { + super({ attr, _roles: [...roles], id }); + } +} + +const { + FIRST_TRACK, + ALL_ALBUMS_WITH_TRACKS_BY_ARTIST, +} = require("./data/media-store.mock"); + +describe("Media Store services", () => { + before("skipping auth", () => { + cds.User = cds.User.Privileged; // skip auth + }); + + it("should bootstrap the services successfully", () => { + const { BrowseTracks, db } = cds.services; + const { Tracks } = BrowseTracks.entities; + + expect(BrowseTracks).not.to.be.undefined; + expect(db).not.to.be.undefined; + expect(Tracks).not.to.be.undefined; + }); + + describe("Tracks", () => { + it("should return track with ID eq 1", async () => { + const { data } = await GET( + "/browse-tracks/Tracks(1)?$expand=genre,album($expand=artist)" + ); + expect(data).to.eql(FIRST_TRACK); + }); + }); + + describe("Albums", () => { + it("should return all albums with tracks by artist", async () => { + const { data } = await GET( + `/browse-tracks/Albums?$filter=artist_ID eq 1&$expand=tracks` + ); + expect(data).to.eql(ALL_ALBUMS_WITH_TRACKS_BY_ARTIST); + }); + }); +}); diff --git a/media-store/util/importData.js b/media-store/util/importData.js deleted file mode 100644 index 9c54899a..00000000 --- a/media-store/util/importData.js +++ /dev/null @@ -1,141 +0,0 @@ -const cds = require("@sap/cds"); -const bcrypt = require("bcryptjs"); -const saltRounds = 10; - -const FIRST_INDEX = 0; -const ZERO_VALUE = 0; -const SECOND_INDEX = 1; -const ID_IF_NOT_FOUND = "ID"; - -const SRC_STORAGE_NAME = "sqlite:chinook.db"; - -const camelCaseToSnake = (str) => - str.replace( - /[a-z][A-Z]/g, - (letters) => - `${letters[FIRST_INDEX].toLowerCase()}_${letters[ - SECOND_INDEX - ].toLowerCase()}` - ); - -const omitID = (str) => { - return str.replace(/_ID$/g, ""); -}; - -const omitId = (str) => { - return str.replace(/Id$/g, ""); -}; - -const chooseFromTargetColumns = (targetColumns) => { - return (srcColumn) => { - const result = targetColumns.find((targetColumn) => { - const one = omitId(srcColumn).toUpperCase(); - const two = omitID(targetColumn).toUpperCase(); - if (one === two) { - return true; - } - return false; - }); - return result ? result : ID_IF_NOT_FOUND; - }; -}; - -const reorderTargetColumns = (srcColumns, targetColumns) => { - const mapColumn = chooseFromTargetColumns(targetColumns); - return srcColumns.map(mapColumn); -}; - -const elementsToColumns = (elements) => { - return Object.values(elements).map((element) => - element.target ? `${element.name}_ID` : element.name - ); -}; - -const constructInsertQuery = (targetEntityName) => { - return (row, columns) => - INSERT.into(targetEntityName).columns(columns).rows(row); -}; - -/** - * The MAIN ISSUE such import is that it depends on: - * - snake case table names - * - camel case column names - * of chinook.db - * There is 'Launch import' task in .vscode folder for debugging. - */ -async function importData(targetDb) { - try { - const targetCSNEntitiesNames = Object.keys(targetDb.entities); - - const someEntry = await targetDb.run( - SELECT.one(targetCSNEntitiesNames[FIRST_INDEX]) - ); - if (!!someEntry) { - return; - } - - const targetCSNEntities = Object.values(targetDb.entities); - const srcStorage = await cds.connect.to(SRC_STORAGE_NAME); - const hashedPassword = await new Promise((resolve, reject) => - bcrypt.hash("some", saltRounds, (error, hash) => { - if (error) { - reject(error); - } - resolve(hash); - }) - ); - console.log("hashedPassword", hashedPassword); - - for (index in targetCSNEntities) { - const targetEntityName = targetCSNEntitiesNames[index]; - console.log(`[LOG]: Processing ${targetEntityName}`); - - const { elements } = targetCSNEntities[index]; - const targetColumns = elementsToColumns(elements); // e.g. ['ID', ..., 'total', 'customer_ID'] - const srcEntityName = camelCaseToSnake(targetEntityName); - const insertQuery = constructInsertQuery(targetEntityName); - let srcResultRows; - try { - srcResultRows = await srcStorage.run(` - SELECT * from ${srcEntityName} - `); // e.g. [ { AlbumId:1, ArtistId:1, Title:'some' }, ... ] - } catch (e) { - console.log("[ERROR]: while trying to read source table", e.message); - continue; - } - if (!srcResultRows || srcResultRows.length < ZERO_VALUE) { - console.log( - `[LOG] Skipping ${targetEntityName}. - There is no data provided in ${SRC_STORAGE_NAME}, ${srcEntityName}` - ); - continue; - } - const srcColumns = Object.keys(srcResultRows[FIRST_INDEX]); - const columns = reorderTargetColumns(srcColumns, targetColumns); - if (new Set(columns).size !== columns.length) { - throw new Error( - `Some ${targetEntityName} column name is mismatched in ${SRC_STORAGE_NAME} ${srcEntityName}` - ); - } - // for mock auth - if (srcEntityName === "Employees" || srcEntityName === "Customers") { - columns.push("password"); - srcResultRows = srcResultRows.map((row) => ({ - ...row, - password: hashedPassword, - })); - } - - const transaction = await targetDb.tx(); - await transaction.run( - srcResultRows.map((row) => insertQuery(Object.values(row), columns)) - ); - await transaction.commit(); - } - console.log("[LOG]: ", "Import completed"); - } catch (errors) { - console.error(errors); - } -} - -module.exports = { importData };