phpsmarter
1/16/2018 - 10:20 AM

books-recompose import script for graphcool

books-recompose import script for graphcool


const _ = require('lodash')
const { Lokka } = require('lokka')
const { Transport } = require('lokka-transport-http')
const debug = require('debug')('Transport')

const client = new Lokka({
  transport: new Transport('https://api.graph.cool/simple/v1/graphcoolendpoint')
})

const createBook = async(book) => {
  const result = await client.mutate(`{
    book: createBook(
      oldId: "${book.id}"
      isbn: "${book.isbn}"
      title: "${book.title}"
    ) {
      id
    }
  }`)
  return result.book.id
}
// this is calling a mutation on the schema. type is book, creates the author
// assigning the author.id to oldId field being created.
const createAuthor = async(author) => {
  const result = await client.mutate(`{
    author: createAuthor(
      oldId: "${author.id}"
      name: "${author.name}"
      author: "${author.author}"
    ) {
      id
    }
  }`)

  return result.author.id
}

// maps from old imported id (data set) to new generated id (Graphcool)
const createBooks = async(rawBooks) => {
  const bookIds = await Promise.all(rawBooks.map(createBook))

  console.log('createBooks');
  return _.zipObject(rawBooks.map(book => book.id), bookIds)
}

const createAuthors = async(rawAuthors) => {
  const authorIds = await Promise.all(rawAuthors.map(createAuthor))
  // console.log(authorIds)
  return _.zipObject(rawAuthors.map(author => author.id), authorIds)
}


const connectBooksAndAuthorsMutation = async(authorId, bookId) => (
  client.mutate(`{
    addToAuthorBooks(authorAuthorId: "${authorId}" booksBookId: "${bookId}") {
      # we don't need this but we need to return something
      booksBook {
        id
      }
    }
  }`)
)

const main = async() => {
  const rawBooks = require('./dbooks.json')
// console.log(rawBooks.)
  const allAuthors = _.chain(rawBooks)
    // console.log(rawBooks)
    .flatMap(rawBook => rawBook.author)
    // console.log(rawBook.author)

    .uniqBy(author => author.id)
    .value()

// create authors
  const authorIdMap = await createAuthors(allAuthors)
  // console.log(authorIdMap)

  console.log(`Created ${Object.keys(authorIdMap).length} authors`)

  // create books
  const bookIdMap = await createBooks(rawBooks)
  console.log(`Created ${Object.keys(bookIdMap).length} books`)

  // connect books and authors
  const mutations = _.chain(rawBooks)
    .flatMap((rawBook) => {
      const newAuthorIds = authorIdMap.push[rawBook.author.id]
      const newBookId = bookIdMap[rawBook.id]

      return newAuthorIds.map((newAuthorId) => ({newAuthorId, newBookId}))
    })
    .map(({newAuthorId, newBookId}) => connectBooksAndAuthorsMutation(newAuthorId, newBookId))
    .value()

  await Promise.all(mutations)
  console.log(`Created ${mutations.length} edges between authors and books`)

}

main().catch((e) => console.error(e))