277 lines
6.5 KiB
JavaScript
277 lines
6.5 KiB
JavaScript
|
const e = require('express')
|
||
|
const database = require('./database.js')
|
||
|
const con = require('./console')
|
||
|
|
||
|
const NO_VALUE = null
|
||
|
const NO_CACHE = undefined
|
||
|
|
||
|
const users = {}
|
||
|
const email_links = {}
|
||
|
const password_links = {}
|
||
|
const session_links = {}
|
||
|
var newest_user = database.getNewestUserId();
|
||
|
|
||
|
const getUserByEmail = (email) => {
|
||
|
const fast = email_links[email]
|
||
|
if (fast === NO_VALUE) {
|
||
|
return undefined
|
||
|
}
|
||
|
if (fast === NO_CACHE) {
|
||
|
const slow = database.getUserByEmail(email)
|
||
|
if (slow === undefined) {
|
||
|
email_links[email] = NO_VALUE
|
||
|
} else {
|
||
|
email_links[email] = slow.id
|
||
|
if (users[slow.id] === NO_CACHE) {
|
||
|
users[slow.id] = slow
|
||
|
}
|
||
|
}
|
||
|
return slow
|
||
|
}
|
||
|
return users[fast]
|
||
|
}
|
||
|
|
||
|
const getUserByPassword = (password) => {
|
||
|
const fast = password_links[password]
|
||
|
if (fast === NO_VALUE) {
|
||
|
return undefined
|
||
|
}
|
||
|
if (fast === NO_CACHE) {
|
||
|
const slow = database.getUserByPassword(password)
|
||
|
if (slow === undefined) {
|
||
|
password_links[password] = NO_VALUE
|
||
|
} else {
|
||
|
password_links[password] = slow.id
|
||
|
if (users[slow.id] === NO_CACHE) {
|
||
|
users[slow.id] = slow
|
||
|
}
|
||
|
}
|
||
|
return slow
|
||
|
}
|
||
|
return users[fast]
|
||
|
}
|
||
|
|
||
|
const getUsers = (ids) => {
|
||
|
const fast = {}
|
||
|
const batch = []
|
||
|
for (const id of ids) {
|
||
|
if (users[id] === NO_CACHE) {
|
||
|
batch.push(id)
|
||
|
} else {
|
||
|
fast[id] = users[id]
|
||
|
}
|
||
|
}
|
||
|
if (batch.length > 0) {
|
||
|
const slow = database.getUsers(batch)
|
||
|
for(const [id, user] of Object.entries(slow)) {
|
||
|
fast[id] = user
|
||
|
}
|
||
|
}
|
||
|
return fast
|
||
|
}
|
||
|
|
||
|
const getUsersPage = (page) => {
|
||
|
const COUNT = 10
|
||
|
const INDEX = newest_user - page * COUNT
|
||
|
const batch = []
|
||
|
for (let i = INDEX; i > INDEX - COUNT && i >= 0; i--) {
|
||
|
batch.push(i)
|
||
|
}
|
||
|
const users = getUsers(batch)
|
||
|
return batch.map(i => users[i]).filter(u => u !== undefined)
|
||
|
}
|
||
|
|
||
|
const register = (first, last, email, password, gender, month, day, year) => {
|
||
|
const data = database.register(first, last, email, password, gender, month, day, year)
|
||
|
if (data === undefined) {
|
||
|
return undefined
|
||
|
}
|
||
|
newest_user = data.user.id
|
||
|
session_links[data.key] = data.user.id
|
||
|
users[data.user.id] = data.user
|
||
|
return data.key
|
||
|
}
|
||
|
|
||
|
const login = (email, pass) => {
|
||
|
const data = database.login(email, pass)
|
||
|
if (data === undefined) {
|
||
|
return undefined
|
||
|
}
|
||
|
session_links[data.key] = data.user.id
|
||
|
users[data.user.id] = data.user
|
||
|
return data.key
|
||
|
}
|
||
|
|
||
|
const logout = (token) => {
|
||
|
|
||
|
if (session_links[token] === NO_VALUE) {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
if (!database.deleteSession(token)) {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
delete session_links[token]
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
const auth = (token) => {
|
||
|
const fast = session_links[token]
|
||
|
if (fast === NO_VALUE) {
|
||
|
return undefined
|
||
|
}
|
||
|
if (fast === NO_CACHE) {
|
||
|
const slow = database.auth(token)
|
||
|
if (slow === undefined) {
|
||
|
session_links[token] = NO_VALUE
|
||
|
} else {
|
||
|
session_links[token] = slow.id
|
||
|
if (users[slow.id] === NO_CACHE) {
|
||
|
users[slow.id] = slow
|
||
|
}
|
||
|
}
|
||
|
return slow
|
||
|
}
|
||
|
return users[fast]
|
||
|
}
|
||
|
|
||
|
const posts = {}
|
||
|
const users_posts = {}
|
||
|
const updated_posts = {}
|
||
|
var newest_post = database.getNewestPostId();
|
||
|
|
||
|
const addPost = (user, content) => {
|
||
|
const id = database.addPost(user, content)
|
||
|
if (id === undefined) {
|
||
|
return -1
|
||
|
}
|
||
|
newest_post = id
|
||
|
if (users_posts[user] === NO_VALUE) {
|
||
|
users[posts] = [id]
|
||
|
} else if (users_posts[user] === NO_CACHE) {
|
||
|
getUsersPosts(user)
|
||
|
} else {
|
||
|
users_posts[user].unshift(id)
|
||
|
}
|
||
|
return id
|
||
|
}
|
||
|
|
||
|
const getPosts = (ids) => {
|
||
|
const fast = {}
|
||
|
const batch = []
|
||
|
for (const id of ids) {
|
||
|
if (posts[id] === NO_CACHE) {
|
||
|
batch.push(id)
|
||
|
} else {
|
||
|
fast[id] = posts[id]
|
||
|
}
|
||
|
}
|
||
|
if (batch.length > 0) {
|
||
|
const slow = database.getPosts(batch)
|
||
|
for(const [id, post] of Object.entries(slow)) {
|
||
|
fast[id] = post
|
||
|
}
|
||
|
}
|
||
|
return fast
|
||
|
}
|
||
|
|
||
|
const getUsersPosts = (user) => {
|
||
|
const fast = users_posts[user]
|
||
|
if (fast === NO_CACHE) {
|
||
|
const posts = database.getUsersPosts(user)
|
||
|
if (posts === undefined) {
|
||
|
users_posts[user] = NO_VALUE
|
||
|
} else {
|
||
|
const slow = []
|
||
|
for (const post in posts) {
|
||
|
slow.push[post.id]
|
||
|
if (posts[post.id] === NO_CACHE) {
|
||
|
posts[post.id] = post
|
||
|
}
|
||
|
}
|
||
|
users_posts[user] = slow
|
||
|
}
|
||
|
return posts
|
||
|
} else {
|
||
|
return getPosts(fast)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const getPostsPage = (page) => {
|
||
|
const COUNT = 10
|
||
|
const INDEX = newest_post - page * COUNT
|
||
|
const batch = []
|
||
|
for (let i = INDEX; i > INDEX - COUNT && i >= 0; i--) {
|
||
|
batch.push(i)
|
||
|
}
|
||
|
const posts = getPosts(batch)
|
||
|
return batch.map(i => posts[i]).filter(p => p !== undefined)
|
||
|
}
|
||
|
|
||
|
const comment = (id, user, content) => {
|
||
|
var fast = posts[id]
|
||
|
if (fast === NO_VALUE) {
|
||
|
return false
|
||
|
} else if (fast === NO_CACHE) {
|
||
|
const slow = getPosts([id])
|
||
|
if (slow[id] === undefined) {
|
||
|
return false
|
||
|
} else {
|
||
|
fast = slow[id]
|
||
|
}
|
||
|
}
|
||
|
fast.comments.push({user, content})
|
||
|
posts[id] = fast
|
||
|
updated_posts[id] = true
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
const like = (id, user, state) => {
|
||
|
var fast = posts[id]
|
||
|
if (fast === NO_VALUE) {
|
||
|
return false
|
||
|
} else if (fast === NO_CACHE) {
|
||
|
const slow = getPosts([id])
|
||
|
if (slow[id] === undefined) {
|
||
|
return false
|
||
|
} else {
|
||
|
fast = slow[id]
|
||
|
}
|
||
|
}
|
||
|
fast.likes[user] = state
|
||
|
posts[id] = fast
|
||
|
updated_posts[id] = true
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
const dump = () => {
|
||
|
for (id in updated_posts) {
|
||
|
const post = posts[id]
|
||
|
if (post === NO_CACHE || post === NO_VALUE) continue;
|
||
|
if (!database.updatePost(post.id, JSON.stringify(post.likes), JSON.stringify(post.comments))) {
|
||
|
con.error(`Failed to saved cached post id ${id}`)
|
||
|
} else {
|
||
|
delete updated_posts.id
|
||
|
}
|
||
|
}
|
||
|
con.msg('Saved cache successfully')
|
||
|
}
|
||
|
|
||
|
module.exports = {
|
||
|
getUserByEmail,
|
||
|
getUserByPassword,
|
||
|
getUsers,
|
||
|
getUsersPage,
|
||
|
register,
|
||
|
login,
|
||
|
logout,
|
||
|
auth,
|
||
|
addPost,
|
||
|
getPosts,
|
||
|
getUsersPosts,
|
||
|
getPostsPage,
|
||
|
comment,
|
||
|
like,
|
||
|
dump
|
||
|
}
|