Created
September 2, 2019 05:43
-
-
Save bc-jasond/499580dc656c484c89289b4be7c3f6f3 to your computer and use it in GitHub Desktop.
dubaniewi.cz content model migration script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ESM - remove after ECMAScript Module support is past Experimental node v14 ? | |
require = require('esm')(module/*, options*/); | |
const { | |
NODE_TYPE_LI, | |
NODE_TYPE_P, | |
NODE_TYPE_A, | |
NODE_TYPE_BOLD, | |
NODE_TYPE_CODE, | |
NODE_TYPE_ITALIC, | |
NODE_TYPE_LINK, | |
NODE_TYPE_SITEINFO, | |
NODE_TYPE_STRIKE, | |
NODE_TYPE_TEXT, | |
SELECTION_ACTION_SITEINFO, | |
SELECTION_ACTION_LINK, | |
SELECTION_ACTION_ITALIC, | |
SELECTION_ACTION_STRIKETHROUGH, | |
SELECTION_ACTION_CODE, | |
SELECTION_ACTION_BOLD, | |
SELECTION_LINK_URL, | |
} = require('../frontend/src/common/constants'); | |
const { | |
Selection, | |
} = require('../frontend/src/pages/edit/edit-selection-helpers'); | |
const { fromJS, List } = require('immutable'); | |
const { | |
getKnex, | |
} = require('./mysql'); | |
async function mang() { | |
const id = 8; | |
const knex = await getKnex(); | |
const [{ user_id, title, canonical, abstract }] = await knex('post') | |
.where('id', id); | |
const [newPostId] = await knex | |
.insert({ user_id, title, canonical, abstract }) | |
.into('post'); | |
const contentNodes = await knex('content_node') | |
.where('post_id', id) | |
.orderBy(['parent_id', 'position']); | |
// keyed off of parent_id | |
const formattingNodes = {}; | |
// nodes with Selection() | |
const pAndLiNodes = {}; | |
// all other nodes, sections, etc. | |
const sectionAndParentNodes = []; | |
// first loop | |
// - add formatting & legacy text nodes to an object keyed on 'parent_id' for later Selection() processing | |
for (let i = 0; i < contentNodes.length; i++) { | |
const node = fromJS({ ...contentNodes[i] }); | |
if ([ | |
NODE_TYPE_A, | |
NODE_TYPE_CODE, | |
NODE_TYPE_SITEINFO, | |
NODE_TYPE_ITALIC, | |
NODE_TYPE_STRIKE, | |
NODE_TYPE_BOLD, | |
NODE_TYPE_LINK, | |
NODE_TYPE_TEXT | |
].includes(node.get('type'))) { | |
if (!formattingNodes[node.get('parent_id')]) { | |
formattingNodes[node.get('parent_id')] = []; | |
} | |
formattingNodes[node.get('parent_id')][node.get('position')] = node; | |
continue; | |
} | |
if ([NODE_TYPE_P, NODE_TYPE_LI].includes(node.get('type'))) { | |
pAndLiNodes[node.get('id')] = node; | |
continue; | |
} | |
sectionAndParentNodes.push(node); | |
} | |
// next loop - add sections and parent nodes (everything but P and LI) to document, add text content where no Selection() is necessary | |
for (let i = 0; i < sectionAndParentNodes.length; i++) { | |
const node = sectionAndParentNodes[i]; | |
const nodeInsertValues = { ...node.toJS(), post_id: newPostId }; | |
nodeInsertValues.content = nodeInsertValues.content || ''; | |
if (formattingNodes[node.get('id')] && formattingNodes[node.get('id')].length === 1 && formattingNodes[node.get('id')][0].get('type') === NODE_TYPE_TEXT) { | |
nodeInsertValues.content = formattingNodes[node.get('id')][0].get('content'); | |
delete formattingNodes[node.get('id')]; | |
} | |
nodeInsertValues.meta = JSON.stringify(nodeInsertValues.meta); | |
await knex('content_node') | |
.insert(nodeInsertValues) | |
} | |
// next loop - for P and LI create Selection() records where necessary | |
for (let nodeWithSelectionId in pAndLiNodes) { | |
let parent = pAndLiNodes[nodeWithSelectionId]; | |
const siblings = formattingNodes[nodeWithSelectionId]; | |
let currentMeta = parent.get('meta'); | |
let currentSelections = currentMeta.get('selections', List()); | |
let currentSelection = new Selection(); | |
let currentEndOffset = 0; | |
for (let i = 0; i < siblings.length; i++) { | |
let current = siblings[i]; | |
if ( | |
current.get('type') === NODE_TYPE_TEXT | |
// text node is only child of P or LI | |
&& siblings.length === 1 | |
) { | |
// just add TEXT node content to parent node - no Selection() mapping needed | |
parent = parent.set('content', current.get('content')); | |
// already updated this node | |
continue; | |
} | |
// Selection() needed | |
while (current.get('type') !== NODE_TYPE_TEXT) { | |
switch (current.get('type')) { | |
case NODE_TYPE_SITEINFO: | |
currentSelection = currentSelection.set(SELECTION_ACTION_SITEINFO, true); | |
break; | |
case NODE_TYPE_A: | |
currentSelection = currentSelection | |
.set(SELECTION_ACTION_LINK, true) | |
.set(SELECTION_LINK_URL, current.get('content')); | |
break; | |
case NODE_TYPE_ITALIC: | |
currentSelection = currentSelection.set(SELECTION_ACTION_ITALIC, true); | |
break; | |
case NODE_TYPE_STRIKE: | |
currentSelection = currentSelection.set(SELECTION_ACTION_STRIKETHROUGH, true); | |
break; | |
case NODE_TYPE_CODE: | |
currentSelection = currentSelection.set(SELECTION_ACTION_CODE, true); | |
break; | |
case NODE_TYPE_BOLD: | |
currentSelection = currentSelection.set(SELECTION_ACTION_BOLD, true); | |
} | |
const currentChildren = formattingNodes[current.get('id')]; | |
// assuming 1 child here... | |
if (currentChildren) { | |
current = currentChildren.shift(); | |
} else { | |
// CODE used to have 'content' too!, need to let the loop happen for formatting but, then break; | |
break; | |
} | |
} | |
const parentContent = parent.get('content') || ''; | |
const currentContent = current.get('content') || ''; | |
currentEndOffset = currentEndOffset += currentContent.length; | |
currentSelection = currentSelection.set('end', currentEndOffset); | |
currentSelections = currentSelections.push(currentSelection); | |
parent = parent | |
.set('content', `${parentContent}${currentContent}`) | |
.set('meta', currentMeta.set('selections', currentSelections)) | |
currentSelection = new Selection({ start: currentEndOffset }); | |
} | |
const insertValues = { ...parent.toJS(), post_id: newPostId }; | |
insertValues.meta = JSON.stringify(insertValues.meta); | |
await knex('content_node') | |
.insert(insertValues); | |
} | |
console.log('KTHXBYE') | |
} | |
mang(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment