// express 모듈 require + 객체화
var express = require('express');
var app = express();
// post data 받기 위해 bodyParser 미들웨어 require
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: false}));
// 템플릿엔진 설정 (view engine : 엔진 종류 설정, views : 폴더 설정)
app.set('view engine','pug');
app.set('views', './views');
app.locals.pretty = true;
// mysql 연결
var mysql = require('mysql');
var conn = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '129329aa',
database : 'TWICE'
});
conn.connect();
// 포트와 연결
app.listen(3000,function(){
console.log('트와이스 플레이리스트에 오신걸 환영합니다!');
});
app.get(['/playlist','/playlist/:id'], function(req,res){ // 메인 + 세부 페이지
// get [] 으로 라우팅 -> 다수의 url 받을 수 있음
var sql = 'SELECT ID, s_name FROM twice_song';
conn.query(sql,function(err,songs_app,fields){
// conn.query()는 인자로 받는 sql문의 해당 행을 콜백함수의 매개변수로 넘김
// songs_app는 데이터베이스의 모든 ID, s_name
// /playlist/:id의 ':id' 는 시멘틱 url의 전달방법
// 시멘틱 url을 받으려면 params 객체 사용
var id = req.params.id; // url로 전달된 id 즉, song.ID
if (id){ // url에 id가 있는 경우 - 하부 페이지 렌더, 단일 row 전달 o
// 라우팅 안에 또 다시 라우팅 -> if 문으로 ;
var sql='SELECT * FROM twice_song where ID = ?'
conn.query(sql, [id], function(err,song_app,fields){
// ? 사용 -> .query 두번째 인자로 [] 전달
// song_app은 id 가 일치하는 하나의 행
if(err){ // 에러 o
console.log(err);
res.status(500).send('Internal Server Error');
// status가 뭔진 모르겠으나 send는 express에서 html을 웹에 출력해준다.
} else { // 에러 x
res.render('view',{songs_pug: songs_app, song_pug:song_app[0]})
// song_app은 배열로 전달되므로 song_app[0] == 헤당 노래의 row
}
});
}else{ // url에 id가 없는 경우 - 메인 페이지 렌더, 단일 row 전달 x
res.render('view', {songs_pug: songs_app});
}
})
});
▽ views/view.pug
doctype html
html
head
meta(charset='utf-8')
body
h1
a(href='/playlist') TWICE
ul
each asong in songs_pug
li
a(href='/playlist/'+asong.ID)= asong.s_name
article
if song_pug
h2= song_pug.s_name
= song_pug.s_desc
else
h2 Welcome
| Welcom to twice's music list!
div
a(href='/playlist/add') add
// get add 페이지 (작성)
app.get('/playlist/add',function(req,res){
// 어째서인지 /:id 보다 먼저 읽어야 한다.
var sql = 'SELECT ID, s_name FROM twice_song';
conn.query(sql,function(err,songs_app,fields){
if(err){ // 에러 o
console.log(err);
res.status(500).send('Internal Server Error');
} else { // 에러 x - add.pug를 렌더해오는데, 변수로 songs_app전달
res.render('add',{songs_pug: songs_app});
}
})
});
// post add 페이지 (데이터 전달받고 리다이렉트, 사용자에겐 보이지 않는 페이지)
app.post('/playlist/add', function(req,res){
var title = req.body.title; // body객체 - post 방식으로 전송한 데이터 받기
var description = req.body.description;
var sql = 'INSERT INTO twice_song (s_name,s_desc) VALUES (?,?)'
conn.query(sql,[title, description], function(err, rows, fields){
// ? 사용 -> .query 두번째 인자로 [] 전달
if(err){
console.log(err);
res.status(500).send('Internal Server Error');
} else {
res.redirect('/playlist/'+rows.insertId);
// redirect는 해당 주소로 리다이렉트 해주는 메서드
// insert문에 해당하는 rows는 ID가 없으므로 ID 대신 insertId 사용
}
})
})
▽ views/add.pug
doctype html
html
head
meta(charset='utf-8')
body
h1
a(href='/playlist') TWICE
ul
each asong in songs_pug
li
a(href='/playlist/'+asong.ID)= asong.s_name
article
form(action='/playlist/add' method='post')
p
input(type='text' name='title' placeholder='title')
p
textarea(name='description' placeholder='description')
p
input(type='submit')
// get edit 페이지 (작성)
app.get('/playlist/:id/edit', function(req,res){
var sql = 'SELECT * FROM twice_song';
conn.query(sql,function(err,songs_app,fields){
var id = req.params.id;
if (id){ // id 있을 때
var sql='SELECT * FROM twice_song where ID = ?'
conn.query(sql, [id], function(err,song_app,fields){
if(err){ // 에러 o
console.log(err);
res.status(500).send('Internal Server Error');
} else { // 에러 x
res.render('edit',{songs_pug: songs_app, song_pug:song_app[0]})
}
})
} else{ // id가 없을 때
console.log(err);
res.status(500).send('Internal Server Error');
}
})
});
// post edit 페이지 (데이터 전달받고 리다이렉트, 사용자에겐 보이지 않는 페이지)
app.post('/playlist/:id/edit', function(req,res){
var sql = 'UPDATE twice_song SET s_name=?, s_desc=? WHERE ID=?';
var title = req.body.title; // body객체:post 방식으로 전송한 데이터 받기
var description = req.body.description;
var id = req.params.id // ID는 form으로 전달받지 못했지만 시멘틱url로 받아올 수 있음
conn.query(sql, [title, description, id], function(err,song_app,fields){
if(err){ // 에러 o
console.log(err);
res.status(500).send('Internal Server Error');
} else { // 에러 x
res.redirect('/playlist/'+id); // 왜인지 '/' 빠뜨리면 안됨
}
})
})
▽ views/edit.pug
doctype html
html
head
meta(charset='utf-8')
body
h1
a(href='/playlist') TWICE
ul
each asong in songs_pug
li
a(href='/playlist/'+asong.ID)= asong.s_name
article
form(action='/playlist/'+song_pug.ID+'/edit' method='post')
p
input(type='text' name='title' placeholder='title' value=song_pug.s_name)
p
textarea(name='description' placeholder='description')
=song_pug.s_desc
p
input(type='submit' value='edit')
페이지삭제는 무조건 post 방식으로 전달되어야 함
(페이지의 모든 링크를 방문하는 플러그인 등이 있을 경우 삭제될 수 있으므로)
app.get('/playlist/:id/delete', function(req,res){
var sql = 'SELECT ID, s_name FROM twice_song';
var id = req.params.id;
conn.query(sql,function(err,songs_app,fields){ // songs_app는 모든 행의 ID, s_name
var sql ='SELECT * FROM twice_song WHERE id=?';
conn.query(sql,[id],function(err,song_app,fields){ // song_app은 id가 일치하는 하나의 행
if(err){ // 에러 o
console.log(err);
res.status(500).send('Internal Server Error');
}
else { // 에러 x
if(song_app===0){ // id값이 없는 범위일때 -> 텅 빈 배열, 길이는 0
console.log('There is no id');
res.status(500).send('Internal Server Error');
}
else {
res.render('delete',{songs_pug: songs_app, song_pug:song_app[0]})
}
}
});
});
});
app.post('/playlist/:id/delete', function(req,res){
var id = req.params.id;
sql = 'DELETE FROM twice_song WHERE id =?';
conn.query(sql,[id],function(err,song_app){
res.redirect('/playlist/');
})
})
▽ views/delete.pug
doctype html
html
head
meta(charset='utf-8')
body
h1
a(href='/playlist') TWICE
ul
each asong in songs_pug
li
a(href='/playlist/'+asong.ID)= asong.s_name
article
h1 Delete? #{song_pug.s_name}
form(action='/playlist/+song_pug.ID+'delete' method='post')
p
input(type='submit' value='YES')
a(href='/playlist/+song_pug.ID) NO