зеркало из https://github.com/DeGsoft/meanjs.git
organizacion y mongo
This commit is contained in:
Родитель
32bb9fb2ab
Коммит
3a28de51e6
|
@ -12,7 +12,7 @@
|
|||
// Usar Transclude para reutilizar el contenido del usuario y hacer la vista más dinámica
|
||||
function cabecera() {
|
||||
return {
|
||||
restrict: 'AE',
|
||||
restrict: 'EA',
|
||||
replace: 'true',
|
||||
transclude: true,
|
||||
templateUrl: '/tpl-cabecera.html'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<section name="Lista">
|
||||
<!-- <p class="lead">Estos son tus movimientos recientes.</p>-->
|
||||
<ab-cabecera>Estos son tus movimientos recientes.</ab-cabecera>
|
||||
<div ab-cabecera>Estos son tus movimientos recientes.</div>
|
||||
<br>
|
||||
<label class="control-label" for="importe">Filtrar:</label>
|
||||
<input type="text" name="filtro" placeholder="qué buscas?" class="input" ng-model="valorBuscado">
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
angular.module('controlCajaApp', ['ui.router','ngCookies', 'ngResource', 'abFiltros','abDirectivas']);
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
angular.module('controlCajaApp', ['ui.router','ngCookies', 'ngResource', 'abFiltros','abDirectivas']);
|
||||
|
||||
angular.module('controlCajaApp').config(function ($stateProvider,$locationProvider) {
|
||||
angular.module('controlCajaApp').config(function ($stateProvider) {
|
||||
$stateProvider
|
||||
.state('total', {
|
||||
url: '/',
|
|
@ -41,18 +41,20 @@
|
|||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-cookies.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-resource.min.js"></script>
|
||||
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js"></script>
|
||||
<script src="app.js"></script>
|
||||
<script src="appHttpLog.js"></script>
|
||||
<script src="appSecurity.js"></script>
|
||||
<script src="registroCtrl.js"></script>
|
||||
<script src="menuCtrl.js"></script>
|
||||
<script src="cajaCtrl.js"></script>
|
||||
<script src="movimientoCtrl.js"></script>
|
||||
<script src="movimientosFactory.js"></script>
|
||||
<script src="maestrosFactory.js"></script>
|
||||
<script src="filtros.js"></script>
|
||||
<script src="directivas.js"></script>
|
||||
<script src="valoracion.js"></script>
|
||||
<!-- reorganización de referencias-->
|
||||
<script src="_comun/app.js"></script>
|
||||
<script src="_comun/states.js"></script>
|
||||
<script src="_comun/appHttpLog.js"></script>
|
||||
<script src="_comun/appSecurity.js"></script>
|
||||
<script src="registro/registroCtrl.js"></script>
|
||||
<script src="_comun/menuCtrl.js"></script>
|
||||
<script src="controlcaja/cajaCtrl.js"></script>
|
||||
<script src="movimiento/movimientoCtrl.js"></script>
|
||||
<script src="data/movimientosFactory.js"></script>
|
||||
<script src="data/maestrosFactory.js"></script>
|
||||
<script src="filtros/filtros.js"></script>
|
||||
<script src="directivas/directivas.js"></script>
|
||||
<script src="directivas/valoracion/valoracion.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"name": "ControlCashFlow",
|
||||
"version": "0.0.0",
|
||||
"description": "Controla tu flujo de caja",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Alberto Basalo",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"express": "~4.12.1",
|
||||
"body-parser": "~1.0.2"
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
https://angular-ui.github.io/
|
||||
http://ngmodules.org/c
|
||||
http://angular-js.in/
|
||||
http://www.directiv.es/
|
||||
|
||||
http://www.tamas.io/node-jsexpress-cors-implementation/
|
||||
http://stackoverflow.com/questions/23823010/how-to-enable-cors-in-angularjs
|
|
@ -1,187 +0,0 @@
|
|||
var express = require('express');
|
||||
var bodyParser = require('body-parser');
|
||||
|
||||
var app = express();
|
||||
app.use(bodyParser());
|
||||
app.use(express.static(__dirname + '/client'));
|
||||
|
||||
app.use(function (peticion, respuesta, siguiente) {
|
||||
console.log("recibida petición: " + peticion.url);
|
||||
if (peticion.body && Object.keys(peticion.body).length>0) {
|
||||
console.log("body: " + JSON.stringify(peticion.body));
|
||||
}
|
||||
siguiente();
|
||||
});
|
||||
|
||||
console.log('ready');
|
||||
|
||||
var maxId = 0;
|
||||
var movimientos = [];
|
||||
var totales = [];
|
||||
|
||||
var usuarios = [];
|
||||
var sesiones = [];
|
||||
|
||||
|
||||
app.use('/api/priv/', function (req, res, next) {
|
||||
var sessionId = req.get('sessionId');
|
||||
var sesion = getSesion(sessionId);
|
||||
if (sesion) {
|
||||
if (esSesionValida(sesion)) {
|
||||
sesion.timeStamp = new Date();
|
||||
req.usuario = sesion.email;
|
||||
next();
|
||||
} else {
|
||||
console.log('Sesión caducada:' + JSON.stringify(sesion));
|
||||
res.status(419).send('Sesión caducada');
|
||||
}
|
||||
} else {
|
||||
res.status(401).send('Credencial inválida');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// API - REST
|
||||
// SECURITY
|
||||
app.route('/api/usuarios')
|
||||
.get(function (req, res, next) {
|
||||
// Esto devuelve la lista completa de usuarios y contraseñas
|
||||
// PELIGRO: Usar sólo a modo de debug mientras desarrollamos
|
||||
res.json(usuarios);
|
||||
})
|
||||
.post(function (req, res, next) {
|
||||
var usuario = req.body;
|
||||
if (existeUsuario(usuario)) {
|
||||
console.log('email ya registrado:' + usuario.email);
|
||||
res.status(409).send('email ' + usuario.email + ' ya registrado');
|
||||
} else {
|
||||
console.log('registrado:' + usuario.email);
|
||||
usuarios.push(usuario);
|
||||
res.json(newSession(usuario.email));
|
||||
}
|
||||
});
|
||||
|
||||
// Gestión de sesiones: listado y login
|
||||
app.route('/api/sesiones')
|
||||
.get(function (req, res, next) {
|
||||
// Esto devuelve la lista completa de sesiones
|
||||
// PELIGRO: Usar sólo a modo de debug mientras desarrollamos
|
||||
res.json(sesiones);
|
||||
})
|
||||
.post(function (req, res, next) {
|
||||
var usuario = req.body;
|
||||
if (esUsuarioValido(usuario)) {
|
||||
console.log('aceptado:' + usuario.email);
|
||||
res.json(newSession(usuario.email));
|
||||
} else {
|
||||
console.log('Credencial inválida:' + usuario.email);
|
||||
res.status(401).send('Credencial inválida');
|
||||
}
|
||||
});
|
||||
|
||||
function existeUsuario(usuario) {
|
||||
return usuarios.some(function (u) {
|
||||
return u.email == usuario.email;
|
||||
});
|
||||
}
|
||||
|
||||
function esUsuarioValido(usuario) {
|
||||
return usuarios.filter(function (u) {
|
||||
return u.email == usuario.email && u.password == usuario.password;
|
||||
})[0];
|
||||
}
|
||||
|
||||
function getSesion(sessionId) {
|
||||
return sesiones.filter(function (s) {
|
||||
return s.sessionId == sessionId;
|
||||
})[0]
|
||||
}
|
||||
|
||||
function esSesionValida(sesion) {
|
||||
return (new Date() - sesion.timeStamp) < 20 * 60 * 1000;
|
||||
}
|
||||
|
||||
function newSession(email) {
|
||||
var sessionId = Math.random() * (88888) + 11111;
|
||||
var timeStamp = new Date();
|
||||
sesiones.push({
|
||||
sessionId: sessionId,
|
||||
email: email,
|
||||
timeStamp: timeStamp
|
||||
});
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
|
||||
// BUSINESS
|
||||
app.get('/api/pub/maestros', function (req, res, next) {
|
||||
var maestros = {
|
||||
categoriasIngresos: ['Nómina', 'Ventas', 'Intereses Depósitos'],
|
||||
categoriasGastos: ['Hipotéca', 'Compras', 'Impuestos']
|
||||
};
|
||||
res.json(maestros);
|
||||
});
|
||||
|
||||
app.route('/api/priv/movimientos')
|
||||
.get(function (req, res, next) {
|
||||
var movimientosUsuario = movimientos.filter(function (m) {
|
||||
return m.usuario = req.usuario;
|
||||
});
|
||||
res.json(movimientosUsuario);
|
||||
})
|
||||
.post(function (req, res, next) {
|
||||
var movimiento = req.body;
|
||||
movimiento.usuario = req.usuario;
|
||||
maxId++;
|
||||
movimiento.id = maxId;
|
||||
movimientos.push(movimiento);
|
||||
var totalUsuario = getTotalUsuario(req.usuario);
|
||||
if (movimiento.tipo == 'Ingreso')
|
||||
totalUsuario.ingresos += movimiento.importe;
|
||||
else
|
||||
totalUsuario.gastos += movimiento.importe;
|
||||
res.status(200).send();
|
||||
});
|
||||
|
||||
app.get('/api/priv/movimientos/:id', function (req, res, next) {
|
||||
var movId = req.params.id;
|
||||
movimientoBuscado = getMovimientoById(movId, req.usuario);
|
||||
res.json(movimientoBuscado);
|
||||
});
|
||||
|
||||
function getMovimientoById(id,usuario) {
|
||||
var movimientoBuscado = movimientos.filter(function (movimiento) {
|
||||
return movimiento.id == id && movimiento.usuario == usuario;
|
||||
})[0];
|
||||
return movimientoBuscado;
|
||||
}
|
||||
|
||||
app.get('/api/priv/total', function (req, res, next) {
|
||||
var totalUsuario = getTotalUsuario(req.usuario);
|
||||
res.json(totalUsuario);
|
||||
});
|
||||
|
||||
function getTotalUsuario(usuario) {
|
||||
if(usuario===undefined) return {};
|
||||
var totalUsuario = totales.filter(function (t) {
|
||||
return t.usuario == usuario;
|
||||
})[0];
|
||||
if (totalUsuario===undefined) {
|
||||
totalUsuario = {
|
||||
usuario : usuario,
|
||||
ingresos: 0,
|
||||
gastos: 0
|
||||
};
|
||||
totales.push(totalUsuario);
|
||||
}
|
||||
return totalUsuario;
|
||||
}
|
||||
|
||||
|
||||
console.log('steady');
|
||||
app.listen(3000);
|
||||
console.log('go');
|
|
@ -1,3 +1,4 @@
|
|||
"use strict";
|
||||
module.exports.routeMaestros = function (app) {
|
||||
app.get('/api/pub/maestros', function (req, res, next) {
|
||||
var maestros = {
|
|
@ -0,0 +1,26 @@
|
|||
"use strict";
|
||||
var movimientosData = require('../data/movimientosData.js');
|
||||
|
||||
module.exports.routeMovimientos = function (app) {
|
||||
|
||||
app.route('/api/priv/movimientos')
|
||||
.get(function (req, res, next) {
|
||||
res.json(movimientosData.getMovimientos(req.usuario));
|
||||
})
|
||||
.post(function (req, res, next) {
|
||||
var movimiento = req.body;
|
||||
movimiento.usuario = req.usuario;
|
||||
movimientosData.postMovimiento(movimiento);
|
||||
res.status(200).send();
|
||||
});
|
||||
|
||||
app.get('/api/priv/movimientos/:id', function (req, res, next) {
|
||||
res.json(movimientosData.getMovimiento(req.params.id, req.usuario));
|
||||
});
|
||||
|
||||
app.get('/api/priv/total', function (req, res, next) {
|
||||
res.json(movimientosData.getTotalUsuario(req.usuario));
|
||||
});
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
"use strict";
|
||||
var seguridadData = require('../data/seguridadData.js');
|
||||
|
||||
module.exports.seguridad = function (app) {
|
||||
|
||||
app.use('/api/priv/', function (req, res, next) {
|
||||
var sessionId = req.get('sessionId');
|
||||
var sesion = seguridadData.getSesion(sessionId);
|
||||
if (sesion) {
|
||||
if (sesion.timeStamp) {
|
||||
req.usuario = sesion.email;
|
||||
next();
|
||||
} else {
|
||||
res.status(419).send('Sesión caducada');
|
||||
}
|
||||
} else {
|
||||
res.status(401).send('Credencial inválida');
|
||||
}
|
||||
});
|
||||
|
||||
// API - REST
|
||||
// SECURITY
|
||||
app.route('/api/usuarios')
|
||||
.post(function (req, res, next) {
|
||||
var usuario = req.body;
|
||||
var sesion = seguridadData.postUsuario(usuario);
|
||||
if (sesion) {
|
||||
res.json(sesion);
|
||||
} else {
|
||||
res.status(409).send('email ' + usuario.email + ' ya registrado');
|
||||
}
|
||||
});
|
||||
|
||||
// Gestión de sesiones: listado y login
|
||||
app.route('/api/sesiones')
|
||||
.post(function (req, res, next) {
|
||||
var usuario = req.body;
|
||||
var sesion = seguridadData.postSesion(usuario);
|
||||
if (sesion) {
|
||||
res.json(sesion);
|
||||
} else {
|
||||
res.status(401).send('Credencial inválida');
|
||||
}
|
||||
});
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
"use strict";
|
||||
var settings = require("./settings.js");
|
||||
var app = require('./express.js').configApp();
|
||||
console.log('ready... settings ok', settings);
|
||||
|
||||
require('./api/seguridadAPI.js').seguridad(app);
|
||||
require('./api/maestrosAPI.js').routeMaestros(app);
|
||||
require('./api/movimientosAPI.js').routeMovimientos(app);
|
||||
console.log('steady... routes OK');
|
||||
|
||||
app.listen(settings.port);
|
||||
console.log('go... listening on port: ' + settings.port);
|
|
@ -0,0 +1,58 @@
|
|||
"use strict";
|
||||
var maxId = 0;
|
||||
var movimientos = [];
|
||||
var totales = [];
|
||||
|
||||
module.exports.getMovimientos = function (usuario) {
|
||||
var movimientosUsuario = movimientos.filter(function (m) {
|
||||
return m.usuario = usuario;
|
||||
});
|
||||
return movimientosUsuario;
|
||||
}
|
||||
|
||||
module.exports.getMovimiento = function (movId, usuario) {
|
||||
var movimientoBuscado = movimientos.filter(function (movimiento) {
|
||||
return movimiento.id == movId && movimiento.usuario == usuario;
|
||||
})[0];
|
||||
return movimientoBuscado;
|
||||
}
|
||||
|
||||
module.exports.getTotalUsuario = function (usuario) {
|
||||
var totalUsuario = getTotalUsuario(usuario);
|
||||
return totalUsuario;
|
||||
}
|
||||
|
||||
module.exports.postMovimiento = function (movimiento) {
|
||||
maxId++;
|
||||
movimiento.id = maxId;
|
||||
movimientos.push(movimiento);
|
||||
var totalUsuario = getTotalUsuario(movimiento.usuario);
|
||||
if (movimiento.tipo == 'Ingreso')
|
||||
totalUsuario.ingresos += movimiento.importe;
|
||||
else
|
||||
totalUsuario.gastos += movimiento.importe;
|
||||
return getMovimientosUsuario(movimiento.usuario);
|
||||
}
|
||||
|
||||
function getMovimientosUsuario(usuario) {
|
||||
var movimientosUsuario = movimientos.filter(function (m) {
|
||||
return m.usuario = usuario;
|
||||
});
|
||||
return movimientosUsuario;
|
||||
}
|
||||
|
||||
function getTotalUsuario(usuario) {
|
||||
if (usuario === undefined) return {};
|
||||
var totalUsuario = totales.filter(function (t) {
|
||||
return t.usuario == usuario;
|
||||
})[0];
|
||||
if (totalUsuario === undefined) {
|
||||
totalUsuario = {
|
||||
usuario: usuario,
|
||||
ingresos: 0,
|
||||
gastos: 0
|
||||
};
|
||||
totales.push(totalUsuario);
|
||||
}
|
||||
return totalUsuario;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
"use strict";
|
||||
var usuarios = [];
|
||||
var sesiones = [];
|
||||
|
||||
module.exports.postUsuario = function (usuario) {
|
||||
if (existeUsuario(usuario)) {
|
||||
console.log('email ya registrado:' + usuario.email);
|
||||
return null;
|
||||
} else {
|
||||
console.log('registrado:' + usuario.email);
|
||||
usuarios.push(usuario);
|
||||
return newSession(usuario.email);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.postSesion = function (usuario) {
|
||||
if (esUsuarioValido(usuario)) {
|
||||
console.log('aceptado:' + usuario.email);
|
||||
return newSession(usuario.email);
|
||||
} else {
|
||||
console.log('Credencial inválida:' + usuario.email);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.getSesion = function (sessionId) {
|
||||
var sesion = getSesion(sessionId);
|
||||
if (sesion) {
|
||||
if (esSesionValida(sesion)) {
|
||||
sesion.timeStamp = new Date();
|
||||
return sesion;
|
||||
} else {
|
||||
console.log('Sesión caducada:' + JSON.stringify(sesion));
|
||||
sesion.timeStamp = null;
|
||||
return sesion;
|
||||
}
|
||||
} else {
|
||||
console.log('Credencial inválida:' + sessionId);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function existeUsuario(usuario) {
|
||||
return usuarios.some(function (u) {
|
||||
return u.email == usuario.email;
|
||||
});
|
||||
}
|
||||
|
||||
function esUsuarioValido(usuario) {
|
||||
return usuarios.filter(function (u) {
|
||||
return u.email == usuario.email && u.password == usuario.password;
|
||||
})[0];
|
||||
}
|
||||
|
||||
function getSesion(sessionId) {
|
||||
return sesiones.filter(function (s) {
|
||||
return s.sessionId == sessionId;
|
||||
})[0]
|
||||
}
|
||||
|
||||
function esSesionValida(sesion) {
|
||||
return (new Date() - sesion.timeStamp) < 20 * 60 * 1000;
|
||||
}
|
||||
|
||||
function newSession(email) {
|
||||
var sessionId = Math.random() * (88888) + 11111;
|
||||
var timeStamp = new Date();
|
||||
sesiones.push({
|
||||
sessionId: sessionId,
|
||||
email: email,
|
||||
timeStamp: timeStamp
|
||||
});
|
||||
return sessionId;
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
"use strict";
|
||||
module.exports.configApp = function () {
|
||||
|
||||
var express = require('express');
|
||||
|
@ -5,8 +6,12 @@ module.exports.configApp = function () {
|
|||
|
||||
var app = express();
|
||||
|
||||
app.use(bodyParser());
|
||||
app.use(bodyParser.urlencoded({
|
||||
extended: true
|
||||
}));
|
||||
app.use(bodyParser.json());
|
||||
app.use(express.static(__dirname + './../client'));
|
||||
console.log("bodyParser y servidor de ficheros estáticos en uso");
|
||||
|
||||
app.use(function (peticion, respuesta, siguiente) {
|
||||
console.log("recibida petición: " + peticion.url);
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "CashFlow",
|
||||
"version": "1.0.0",
|
||||
"description": "Ejemplo para formacioón MEANJS",
|
||||
"main": "cash-flow.js",
|
||||
"author": "info@agorabinaria.com",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"body-parser": "^1.12.0",
|
||||
"express": "^4.12.2"
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"name": "ControlCashFlow",
|
||||
"version": "0.0.0",
|
||||
"description": "Controla tu flujo de caja",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Alberto Basalo",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"express": "~4.12.1",
|
||||
"body-parser": "~1.0.2"
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
var app = require('./server/config.js').configApp();
|
||||
require('./server/seguridad.js').seguridad(app);
|
||||
console.log('ready');
|
||||
|
||||
require('./server/maestros.js').routeMaestros(app);
|
||||
require('./server/movimientos.js').routeMovimientos(app);
|
||||
console.log('steady');
|
||||
|
||||
app.listen(3000);
|
||||
console.log('go');
|
|
@ -1,63 +0,0 @@
|
|||
var maxId = 0;
|
||||
var movimientos = [];
|
||||
var totales = [];
|
||||
|
||||
module.exports.routeMovimientos = function (app) {
|
||||
|
||||
|
||||
app.route('/api/priv/movimientos')
|
||||
.get(function (req, res, next) {
|
||||
var movimientosUsuario = movimientos.filter(function (m) {
|
||||
return m.usuario = req.usuario;
|
||||
});
|
||||
res.json(movimientosUsuario);
|
||||
})
|
||||
.post(function (req, res, next) {
|
||||
var movimiento = req.body;
|
||||
movimiento.usuario = req.usuario;
|
||||
maxId++;
|
||||
movimiento.id = maxId;
|
||||
movimientos.push(movimiento);
|
||||
var totalUsuario = getTotalUsuario(req.usuario);
|
||||
if (movimiento.tipo == 'Ingreso')
|
||||
totalUsuario.ingresos += movimiento.importe;
|
||||
else
|
||||
totalUsuario.gastos += movimiento.importe;
|
||||
res.status(200).send();
|
||||
});
|
||||
|
||||
app.get('/api/priv/movimientos/:id', function (req, res, next) {
|
||||
var movId = req.params.id;
|
||||
movimientoBuscado = getMovimientoById(movId, req.usuario);
|
||||
res.json(movimientoBuscado);
|
||||
});
|
||||
|
||||
function getMovimientoById(id, usuario) {
|
||||
var movimientoBuscado = movimientos.filter(function (movimiento) {
|
||||
return movimiento.id == id && movimiento.usuario == usuario;
|
||||
})[0];
|
||||
return movimientoBuscado;
|
||||
}
|
||||
|
||||
app.get('/api/priv/total', function (req, res, next) {
|
||||
var totalUsuario = getTotalUsuario(req.usuario);
|
||||
res.json(totalUsuario);
|
||||
});
|
||||
|
||||
function getTotalUsuario(usuario) {
|
||||
if (usuario === undefined) return {};
|
||||
var totalUsuario = totales.filter(function (t) {
|
||||
return t.usuario == usuario;
|
||||
})[0];
|
||||
if (totalUsuario === undefined) {
|
||||
totalUsuario = {
|
||||
usuario: usuario,
|
||||
ingresos: 0,
|
||||
gastos: 0
|
||||
};
|
||||
totales.push(totalUsuario);
|
||||
}
|
||||
return totalUsuario;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
var usuarios = [];
|
||||
var sesiones = [];
|
||||
|
||||
module.exports.seguridad = function (app) {
|
||||
|
||||
app.use('/api/priv/', function (req, res, next) {
|
||||
var sessionId = req.get('sessionId');
|
||||
var sesion = getSesion(sessionId);
|
||||
if (sesion) {
|
||||
if (esSesionValida(sesion)) {
|
||||
sesion.timeStamp = new Date();
|
||||
req.usuario = sesion.email;
|
||||
next();
|
||||
} else {
|
||||
console.log('Sesión caducada:' + JSON.stringify(sesion));
|
||||
res.status(419).send('Sesión caducada');
|
||||
}
|
||||
} else {
|
||||
res.status(401).send('Credencial inválida');
|
||||
}
|
||||
});
|
||||
// API - REST
|
||||
// SECURITY
|
||||
app.route('/api/usuarios')
|
||||
.get(function (req, res, next) {
|
||||
// Esto devuelve la lista completa de usuarios y contraseñas
|
||||
// PELIGRO: Usar sólo a modo de debug mientras desarrollamos
|
||||
res.json(usuarios);
|
||||
})
|
||||
.post(function (req, res, next) {
|
||||
var usuario = req.body;
|
||||
if (existeUsuario(usuario)) {
|
||||
console.log('email ya registrado:' + usuario.email);
|
||||
res.status(409).send('email ' + usuario.email + ' ya registrado');
|
||||
} else {
|
||||
console.log('registrado:' + usuario.email);
|
||||
usuarios.push(usuario);
|
||||
res.json(newSession(usuario.email));
|
||||
}
|
||||
});
|
||||
|
||||
// Gestión de sesiones: listado y login
|
||||
app.route('/api/sesiones')
|
||||
.get(function (req, res, next) {
|
||||
// Esto devuelve la lista completa de sesiones
|
||||
// PELIGRO: Usar sólo a modo de debug mientras desarrollamos
|
||||
res.json(sesiones);
|
||||
})
|
||||
.post(function (req, res, next) {
|
||||
var usuario = req.body;
|
||||
if (esUsuarioValido(usuario)) {
|
||||
console.log('aceptado:' + usuario.email);
|
||||
res.json(newSession(usuario.email));
|
||||
} else {
|
||||
console.log('Credencial inválida:' + usuario.email);
|
||||
res.status(401).send('Credencial inválida');
|
||||
}
|
||||
});
|
||||
|
||||
function existeUsuario(usuario) {
|
||||
return usuarios.some(function (u) {
|
||||
return u.email == usuario.email;
|
||||
});
|
||||
}
|
||||
|
||||
function esUsuarioValido(usuario) {
|
||||
return usuarios.filter(function (u) {
|
||||
return u.email == usuario.email && u.password == usuario.password;
|
||||
})[0];
|
||||
}
|
||||
|
||||
function getSesion(sessionId) {
|
||||
return sesiones.filter(function (s) {
|
||||
return s.sessionId == sessionId;
|
||||
})[0]
|
||||
}
|
||||
|
||||
function esSesionValida(sesion) {
|
||||
return (new Date() - sesion.timeStamp) < 20 * 60 * 1000;
|
||||
}
|
||||
|
||||
function newSession(email) {
|
||||
var sessionId = Math.random() * (88888) + 11111;
|
||||
var timeStamp = new Date();
|
||||
sesiones.push({
|
||||
sessionId: sessionId,
|
||||
email: email,
|
||||
timeStamp: timeStamp
|
||||
});
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
# 01 - Introducción a MongoDB
|
||||
|
||||
## 01.1 - Documentos JSON
|
||||
[ver](./01.1-introduccion.md)
|
||||
|
||||
## 01.2 - Bases de datos y colecciones de documentos
|
||||
[ver](./01.2-nomenclatura.md)
|
||||
|
||||
## 01.3 - Puntos fuertes
|
||||
[ver](./01.3-puntos-fuertes.md)
|
||||
|
||||
## 01.4 - Puntos débiles
|
||||
[ver](./01.4-puntos-debiles.md)
|
||||
|
||||
## 01.5 - Indicaciones
|
||||
[ver](./01.5-indicaciones.md)
|
|
@ -0,0 +1,26 @@
|
|||
# 01 - Introducción a MongoDB
|
||||
|
||||
## 01.1 - Documentos JSON
|
||||
MongoDB es una **base de datos documental** que guarda la información en **documentos** en formato **JSON.**
|
||||
|
||||
```javascript
|
||||
{
|
||||
"_id": "2015-125000369",
|
||||
"fecha": "2015-04-01T19:09:48.388Z",
|
||||
"importe": 1100,
|
||||
"cliente" : {
|
||||
"nombre" : "Industria Comercial S.A.",
|
||||
"nif" : "A15326985"
|
||||
},
|
||||
"productos" : [
|
||||
{
|
||||
"referencia" : "zm-35",
|
||||
"cantidad" : 4 ,
|
||||
"precio": 300
|
||||
},
|
||||
{
|
||||
"descuento": -100
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
|
@ -0,0 +1,24 @@
|
|||
# 01 - Introducción a MongoDB
|
||||
|
||||
## 01.2 - Bases de datos y colecciones de documentos
|
||||
Los **documentos** se almacenan en **colecciones**, pero MongoDB no impone ninguna **restricción de esquema** que deben cumplir para ser *aceptados*.
|
||||
|
||||
Se llama **base de datos** al conjunto de colecciones que sirven a un propósito y que comparten medidas de seguridad, réplica y distribución.
|
||||
|
||||
Un mismo **servidor** puede atender distintas bases de datos.
|
||||
|
||||
```javascript
|
||||
{
|
||||
"servidor": "datos.acme.com:27017",
|
||||
"databases" : [
|
||||
{
|
||||
"name" : "facturacion",
|
||||
"collections" : ["clientes","facturas","cobros"]
|
||||
},
|
||||
{
|
||||
"name" : "almacen",
|
||||
"collections" : ["productos","albaranes"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
|
@ -0,0 +1,20 @@
|
|||
# 01 - Introducción a MongoDB
|
||||
|
||||
## 01.3 - Puntos fuertes
|
||||
|
||||
### Velocidad
|
||||
#### Entrada
|
||||
- Sin restricciones de esquema.
|
||||
- Sin integridad referencial.
|
||||
#### Salida
|
||||
- Indices por cualquier campo.
|
||||
- Documentos complejos sin Joins.
|
||||
- Réplicas vivas en tiempo real.
|
||||
#### Desarrollo
|
||||
- El esquema se define sólo a nivel de aplicación.
|
||||
- Si el lenguaje admite JSON el intercambio de datos es directo.
|
||||
|
||||
### Alta Disponibilidad
|
||||
#### Réplica
|
||||
- Maestro y esclavos.
|
||||
- Cambio de roles *en caliente*.
|
|
@ -0,0 +1,18 @@
|
|||
# 01 - Introducción a MongoDB
|
||||
|
||||
## 01.4 - Puntos débiles
|
||||
|
||||
### Transacciones
|
||||
#### Velocidad sobre precisión
|
||||
- La responsabilidad recae en las aplicaciones.
|
||||
#### El documento es la unidad transaccional
|
||||
- Se garantiza la integridad a nivel de documento.
|
||||
- Los documentos pueden contener a otros documentos *relacionados*
|
||||
|
||||
|
||||
### Joins
|
||||
#### Sin integridad referencial
|
||||
- La responsabilidad recae en las aplicaciones.
|
||||
#### El documento es la unidad informacional
|
||||
- Se fomenta el acceso secuencial.
|
||||
- Los documentos pueden contener a otros documentos *relacionados*
|
|
@ -0,0 +1,16 @@
|
|||
# 01 - Introducción a MongoDB
|
||||
|
||||
## 01.5 - Indicaciones
|
||||
|
||||
Aplicaciones que requieran alguna de las siguientes **V´s**
|
||||
|
||||
### Velocidad
|
||||
|
||||
### Volumen
|
||||
|
||||
### Variedad
|
||||
|
||||
En general encajan bien en este grupo las
|
||||
- aplicaciones en la nube,
|
||||
- integración de sistemas y
|
||||
- análisis de información
|
|
@ -0,0 +1,7 @@
|
|||
# 02 - Instalación y puesta en marcha
|
||||
|
||||
## 02.1 - Servidor y clientes
|
||||
[ver](./02.1-servidor-y-clientes-md)
|
||||
|
||||
## 02.2 - Arranque y configuración
|
||||
[ver](./02.1-servidor-y-clientes-md)
|
|
@ -0,0 +1,27 @@
|
|||
# 02 - Instalación y puesta en marcha
|
||||
|
||||
## 02.1 - Servidor y clientes
|
||||
En la web de [MongoDB](http://www.mongodb.org/downloads) se dispone de los paquetes de descarga para distinas versiones, plataformas y arquitecturas.
|
||||
|
||||
Estructura común de instalación
|
||||
```
|
||||
/mongo
|
||||
/bin
|
||||
/mongod
|
||||
/mongo
|
||||
/mongoimport
|
||||
/monogexport
|
||||
/mongodump/mongorestore
|
||||
/...
|
||||
/data
|
||||
/mongod.lock
|
||||
/storage.bson
|
||||
/journal
|
||||
/j._0
|
||||
/facturacion.0
|
||||
/facturacion.ns
|
||||
/almacen.o
|
||||
/almacen.ns
|
||||
/conf
|
||||
/mongodb.conf
|
||||
```
|
|
@ -0,0 +1,32 @@
|
|||
# 02 - Instalación y puesta en marcha
|
||||
|
||||
## 02.2 - Arranque y configuración
|
||||
|
||||
Para arrancar una instancia de un servidor MonogDB se ejecuta el programa `mongod` dentro del directorio `/bin` Un ejemplo común de inicio es:
|
||||
```
|
||||
./mongod --dbpath ../data
|
||||
```
|
||||
|
||||
### Configuración
|
||||
Aunque el comando de instalación admite numerosos argumentos, es común guardarlos en un archivo de configuración en formato **YAML**.
|
||||
```
|
||||
./mongod --config ../conf/mongodb.conf
|
||||
```
|
||||
Este podría ser un ejemplo de configuración
|
||||
```yaml
|
||||
systemLog:
|
||||
destination: file
|
||||
path: "/var/log/mongodb/mongodb.log"
|
||||
logAppend: true
|
||||
storage:
|
||||
dbPath: ../data
|
||||
journal:
|
||||
enabled: true
|
||||
processManagement:
|
||||
fork: true
|
||||
net:
|
||||
bindIp: 127.0.0.1
|
||||
port: 27017
|
||||
setParameter:
|
||||
enableLocalhostAuthBypass: false
|
||||
```
|
|
@ -0,0 +1,52 @@
|
|||
# 03 - Interacción
|
||||
|
||||
## 03.1 - mongo (consola, terminal)
|
||||
|
||||
```javascript
|
||||
// iniciar la consola de mongo
|
||||
./bin/mongo
|
||||
// mostrar las bases de datos
|
||||
show dbs
|
||||
// acceso o creación de una base de datos
|
||||
use facturacion
|
||||
// creación explicita de una collecion en la base de datos actual
|
||||
db.createCollection('clientes')
|
||||
// mostrar las colecciones de la base de datos actual
|
||||
show collections
|
||||
// inserción de un objeto simple
|
||||
db.clientes.insert({nif:'B15123456', nombre:'Industrias comerciales SA'});
|
||||
// contenido completo de una colección
|
||||
db.clientes.find()
|
||||
// inserción de un objeto con un objeto incrustado
|
||||
db.clientes.insert({nif:'B1545678', nombre:'Electrodomésticos SigloXX', direccion:{calle:'Juan Florez', cp:15005, ciudad:'A Coruña'}})
|
||||
// inserción de un objeto con un objeto incrustado y un array de valores
|
||||
db.clientes.insert({nif:'B159876', nombre:'Congelados DelMar', direccion:{calle:'Puerto', cp:'15005', ciudad:'A Coruña'}, telefonos:['98456789','607881133']})
|
||||
// inserción de un objeto con un objeto incrustado y un array de valores y array de objetos
|
||||
db.clientes.insert({nif:'B15666777', nombre:'Hernández y Fernández Abogados', direccion:{calle:'Cantón Grande', cp:'15003', ciudad:'A Coruña'}, telefonos:['98456789','607881133'], contactos:[{nombre:'Juan Hernández', email:'juan.hernandez@gmail.com'},{nombre:'José Fernández', email:'jose.fernandez@gmail.com'}]})
|
||||
db.clientes.find()
|
||||
// creación automatica de una colección
|
||||
// inserción de fechas
|
||||
db.facturas.insert({nif:'B15123456', fecha: new Date(2015,04-1,03,12), importe:2345.47})
|
||||
db.facturas.find()
|
||||
// inserción de objetos complejos
|
||||
db.facturas.insert({nif:'B15123456', fecha: new Date(2015,04-1,03,12), importe:2345.47, lineas:[{item:'ar-3451', cantidad:3, importe:11.53},{item:'zr-2345', cantidad:23, importe:3.45}]})
|
||||
db.facturas.find()
|
||||
// renombrar una colección
|
||||
db.clientes.renameCollection('terceros')
|
||||
// comprobar y contar el contenido
|
||||
db.terceros.count()
|
||||
// eliminar una colección
|
||||
db.terceros.drop()
|
||||
show collections
|
||||
// eliminar una base de datos
|
||||
db.dropDatabase()
|
||||
show dbs
|
||||
// pedir ayuda
|
||||
help
|
||||
// salir
|
||||
exit
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 03.2 - Robomongo (GUI)
|
|
@ -0,0 +1,33 @@
|
|||
# 03 - Interacción
|
||||
|
||||
## 03.2 - import
|
||||
|
||||
```javascript
|
||||
// importar desde un fichero json
|
||||
// mongoimport uno de los comandos de consola que acompañan a mongo
|
||||
// --db en qué base de datos
|
||||
// --collection en qué colección
|
||||
// --file ruta del fichero
|
||||
// --type formato y particularidades
|
||||
mongoimport --db geodata --collection countries --file countries_basic.json --type json --jsonArray
|
||||
// consola de administracion
|
||||
mongo
|
||||
// comprabación de la importación
|
||||
use geodata
|
||||
db.countries.stats()
|
||||
db.countries.stats({scale:1024})
|
||||
db.countries.find()
|
||||
// iteración para cursores grandes
|
||||
it
|
||||
it
|
||||
// para verlo bonito
|
||||
db.countries.find().pretty()
|
||||
// búsquedas básicas
|
||||
db.countries.findOne()
|
||||
db.countries.find({})
|
||||
db.countries.find({countryCode:'ES'})
|
||||
db.countries.find({continent:'EU'})
|
||||
db.countries.find({currencyCode:'EUR'})
|
||||
db.countries.find({currencyCode:'EUR'},{countryName:1, population:1})
|
||||
db.countries.find({currencyCode:'EUR'},{countryName:1, population:1, _id:0})
|
||||
```
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,38 @@
|
|||
# 04 find
|
||||
|
||||
## 04.1 find()
|
||||
|
||||
Todas las búsquedas se realizan sobre **una colección sin joins**
|
||||
|
||||
```javascript
|
||||
|
||||
// BUSCAR TODOS
|
||||
db.countries.find()
|
||||
// select * from countries
|
||||
|
||||
// BUSCAR TODOS PROYECCIÓN
|
||||
db.countries.find({currencyCode:'EUR'},{countryName:1, population:1})
|
||||
// select _id, countryName, population from countries
|
||||
db.countries.find({currencyCode:'EUR'},{countryName:1, population:1, _id:0})
|
||||
// select countryName, population from countries
|
||||
|
||||
// BUSCAR TODOS ORDENADO
|
||||
db.countries.find().sort({countryName:1})
|
||||
// select * from countries order by countryName asc
|
||||
db.countries.find().sort({countryName:-1})
|
||||
// select * from countries order by countryName desc
|
||||
db.countries.find().sort({continentName:1, countryName:1})
|
||||
// select * from countries order by continentName asc, countryName asc
|
||||
|
||||
// BUSCAR LOS 10 PRIMEROS DE TODOS ORDENADO
|
||||
db.countries.find().sort({continentName:1, countryName:1}).limit(10)
|
||||
// select top 10 * from countries order by countryName asc
|
||||
// buscar los 10 siguientes de todos ordenado
|
||||
db.countries.find().sort({continentName:1, countryName:1}).skip(10).limit(10)
|
||||
// select top 10 * from countries order by countryName asc y algo más ....
|
||||
|
||||
// BUSCAR CUANTOS HAY EN TOTAL
|
||||
db.countries.find().count()
|
||||
// select count(*) from countries
|
||||
|
||||
```
|
|
@ -0,0 +1,36 @@
|
|||
# 04 find
|
||||
|
||||
## 04.2 find({key:value})
|
||||
|
||||
Son las consultas equivalentes al conocido **where**
|
||||
|
||||
### {key:value}
|
||||
|
||||
### {key:{$op:value}}
|
||||
|
||||
### {key1:value1, key2:value2}
|
||||
|
||||
### {$boolop:[ {key1:{$op1:value1}} ,{key2:{$op2:value2}} ]}
|
||||
|
||||
```javascript
|
||||
|
||||
// BUSCAR UN PAIS CON countryCode ES
|
||||
db.countries.find({countryCode:'ES'})
|
||||
// select * from countries where countryCode == 'ES'
|
||||
|
||||
// BUSCAR PAISES FUERA DE EUROPA
|
||||
db.countries.find({continent:{$ne:'EU'}})
|
||||
// select * from countries where continent <> 'EU'
|
||||
|
||||
// BUSCAR PAISES FUERA DE EUROPA CON EUROS
|
||||
db.countries.find({continent:{$ne:'EU'}, currencyCode:'EUR'})
|
||||
// select * from countries where continent <> 'EU' and currencyCode = 'EUR'
|
||||
|
||||
// BUSCAR PAISES DE América del Norte o del Sur
|
||||
db.countries.find({$or:[{continent:'NA'},{continent:'SA'}]})
|
||||
// select * from countries where continent == 'NA' or continent == 'SA'
|
||||
|
||||
// BUSCAR PAISES DE América del Norte o del Sur
|
||||
db.countries.find({continent: {$in:['NA','SA']}})
|
||||
// select * from countries where continent == 'NA' or continent == 'SA'
|
||||
```
|
|
@ -0,0 +1,42 @@
|
|||
# 04 find
|
||||
|
||||
## 04.2 find({key:{'$regex': /valor/}})
|
||||
|
||||
Las expresiones regulares permiten **condiciones de busqueda** complejas
|
||||
|
||||
```javascript
|
||||
|
||||
// BUSCAR PAISES DE América del Norte o del Sur
|
||||
db.countries.find({continentName:/America/})
|
||||
// select * from countries where continentName like '%America%'
|
||||
|
||||
// BUSCAR PAISES DE América del Norte o del Sur EN MINUSCULAS
|
||||
db.countries.find({continentName:/america/})
|
||||
// select * from countries where continentName like '%america%'
|
||||
|
||||
// BUSCAR PAISES DE América del Norte o del Sur EN MINUSCULAS OK
|
||||
db.countries.find({continentName:/america/i})
|
||||
// select * from countries where continentName like '%america%'
|
||||
|
||||
// BUSCAR PAISES DE América del Norte o del Sur EN MINUSCULAS OK
|
||||
db.countries.find({continentName:/america/i})
|
||||
// select * from countries where continentName like '%america%'
|
||||
|
||||
// BUSCAR PAISES DE que empiezan por Republic
|
||||
db.countries.find({countryName:/^republic/i})
|
||||
// select * from countries where countryName like 'republic%'
|
||||
|
||||
// BUSCAR PAISES DE que terminan en Republic
|
||||
db.countries.find({countryName:/republic$/i})
|
||||
// select * from countries where countryName like '%republic'
|
||||
|
||||
// BUSCAR PAISES QUE HABLEN ESPAÑOL
|
||||
db.countries.find({languages:/es/})
|
||||
// select * from countries where countryName like '%es%'
|
||||
|
||||
// BUSCAR COMODINES
|
||||
db.countries.find({countryName:{'$regex': 'A.a'}})
|
||||
// select * from countries where countryName like 'A?a'
|
||||
db.countries.find({countryName:{'$regex': 'A*a'}})
|
||||
// select * from countries where countryName like 'A%a'
|
||||
```
|
|
@ -0,0 +1,128 @@
|
|||
# 04 find
|
||||
|
||||
## 04.4 find() in array []
|
||||
|
||||
Buscar dentro de los **elementos de un array**
|
||||
|
||||
```javascript
|
||||
mongoimport --db crm --collection people --file contacts.json --type json --jsonArray
|
||||
|
||||
|
||||
// BÚSQUEDAS SIMPLES
|
||||
//cada persona de la colección people tiene un campo tags, que es un array de strings.
|
||||
db.people.find({tags:"laborum"},{name:1,tags:1});
|
||||
|
||||
// QUE ESTÉN TODOS
|
||||
// Personas que contengan “laborum” y “sunt” en el campo tags
|
||||
|
||||
db.people.find(
|
||||
{
|
||||
tags:
|
||||
{
|
||||
$all:["laborum","sunt"]
|
||||
}
|
||||
},
|
||||
{name:1,tags:1});
|
||||
|
||||
|
||||
// QUE ESTÉN ALGUNOS
|
||||
// Documentos que tengan en el campo tags alguno de los tres elementos posibles
|
||||
|
||||
db.people.find(
|
||||
{
|
||||
tags:
|
||||
{
|
||||
$in:["laborum","sunt","nisi"]
|
||||
}
|
||||
},
|
||||
{name:1,tags:1});
|
||||
|
||||
// QUE NO ESTÉ NINGUNO
|
||||
//Documentos que NO contengan los elementos especificados en el array de entrada
|
||||
|
||||
db.people.find(
|
||||
{
|
||||
tags:
|
||||
{
|
||||
$nin:["laborum","sunt","nisi"]
|
||||
}
|
||||
},
|
||||
{name:1,tags:1});
|
||||
|
||||
// POR TAMAÑO DEL ARRAY
|
||||
//Todos los documentos cuyo array de tags tiene un tamaño 3
|
||||
|
||||
db.people.find({tags:{$size:3}})
|
||||
|
||||
// POR POSICIÓN
|
||||
//Los arrays comienzan en 0, y tags.1 tiene que ir entre comillas.
|
||||
db.people.find({"tags.1":"enim"});
|
||||
|
||||
// PROYECTAR TROZOS DE UN ARRAY
|
||||
//El “tags.$”:1 sirve para devolver el primer elemento del array de tags, de los documentos encontrados.
|
||||
|
||||
db.contacts.find(
|
||||
{
|
||||
tags:
|
||||
{
|
||||
$in:["sunt","esse"]
|
||||
}
|
||||
},
|
||||
{"tags.$":1,name:1});
|
||||
//Elementos que contienen el subdocumento compuesto por el id 1 y el nombre “Trinity Ford”
|
||||
|
||||
db.people.find(
|
||||
{
|
||||
friends:
|
||||
{
|
||||
id:1,
|
||||
name:"Trinity Ford"
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//Todos los documentos que cumplen el “friends.name”:”Trinity Ford” independientemente del id que tengan.
|
||||
|
||||
db.people.find({"friends.name":"Trinity Ford"});
|
||||
|
||||
//Buscamos en el array friends los elementos que estén en la posición 2 y cuyo nombre sea mayor o igual que T.
|
||||
|
||||
db.people.find(
|
||||
{
|
||||
"friends.2.name":{$gte:"T"}
|
||||
},
|
||||
{friends:1,name:1});
|
||||
|
||||
|
||||
// Con **$slice** se devuelve un número determinado de elementos de un array
|
||||
|
||||
// En la proyección mostramos el último elemento de la lista de amigos
|
||||
|
||||
db.people.find({
|
||||
"friends.2.name": {
|
||||
$gte: "T"
|
||||
}
|
||||
}, {
|
||||
friends: {
|
||||
$slice: -1
|
||||
},
|
||||
name: 1
|
||||
});
|
||||
|
||||
|
||||
|
||||
db.people.find(
|
||||
{
|
||||
tags:
|
||||
{
|
||||
$in:["laborum","sunt","nisi"]
|
||||
}
|
||||
},
|
||||
{
|
||||
tags:{$slice:3},
|
||||
name:1
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
```
|
|
@ -0,0 +1,150 @@
|
|||
# 04 find
|
||||
|
||||
## 04.5 find() extra
|
||||
|
||||
Búsquedas complejas ** por existencia, por tipo, lógicas...**
|
||||
|
||||
```javascript
|
||||
mongoimport --db people --collection contacts --file contacts.json --type json --jsonarray
|
||||
|
||||
|
||||
// POR EXISTENCIA DE CAMPO
|
||||
// Gente *con trabajo*, en los que existe el campo company
|
||||
|
||||
db.people.find(
|
||||
{
|
||||
company:{$exists:true}
|
||||
},
|
||||
{
|
||||
name:1,
|
||||
age:1,
|
||||
company:1
|
||||
}
|
||||
);
|
||||
|
||||
// POR TIPO DE DATOS
|
||||
[Tipos de datos y sus códigos](http://docs.mongodb.org/manual/reference/operator/query/type/#op._S_type)
|
||||
|
||||
db.people.find(
|
||||
{
|
||||
company:{$type:2}
|
||||
},
|
||||
{
|
||||
name:1,
|
||||
age:1,
|
||||
company:1
|
||||
}
|
||||
);
|
||||
|
||||
// POR COMPARADORES COMPLEJOS
|
||||
|
||||
// Chicas o mayores de 20 años (Where gender = "female" OR age>20)
|
||||
|
||||
db.people.find(
|
||||
{ $or:
|
||||
[
|
||||
{gender:"female"},
|
||||
{age:{$gt:20}}
|
||||
]
|
||||
},
|
||||
{
|
||||
name:1,
|
||||
gender:1,
|
||||
age:1
|
||||
}
|
||||
);
|
||||
|
||||
// EL OPERADOR $and ¿ES NECESARIO?
|
||||
|
||||
//Ejemplo 1 and implicito
|
||||
db.people.find(
|
||||
{
|
||||
gender:"female",
|
||||
age:{$gt:20}
|
||||
},
|
||||
{name:1,gender:1,age:1}
|
||||
);
|
||||
|
||||
//Ejemplo 2 and explicito pero innecesario
|
||||
db.people.find(
|
||||
{
|
||||
$and:
|
||||
[
|
||||
{gender:"female"},
|
||||
{age:{$gt:20}}
|
||||
]
|
||||
},
|
||||
{name:1,gender:1,age:1} )
|
||||
|
||||
|
||||
// Ejemplos 3 y 4: and siendo util, para condiciones sobre la misma variable
|
||||
|
||||
//Ejemplo 3 OK
|
||||
db.people.find(
|
||||
{
|
||||
age:{$gt:30},
|
||||
age:{$lt:40}
|
||||
},
|
||||
{name:1,gender:1,age:1}
|
||||
);
|
||||
|
||||
//Ejemplo 4 FAIL
|
||||
db.people.find(
|
||||
{
|
||||
age:{$lt:40},
|
||||
age:{$gt:30}
|
||||
},
|
||||
{name:1,gender:1,age:1}
|
||||
);
|
||||
//MongoDB coge el último valor para realizar la consulta
|
||||
|
||||
// CONSULTAS COMPLEJAS
|
||||
// Menores de 30 años, o mujeres mayores de 50
|
||||
|
||||
db.people.find(
|
||||
{
|
||||
$or:
|
||||
[
|
||||
{age:{$lt:30}},
|
||||
{
|
||||
$and:[
|
||||
{age:{$gt:50}},
|
||||
{gender:"female"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
// $nor QUE NADA SEA CIERTO
|
||||
|
||||
//Personas cuya edad NO sea mayor que 30 y cuyo campo isActive NO sea true.
|
||||
|
||||
db.people.find(
|
||||
{
|
||||
$nor:
|
||||
[
|
||||
{age:{$gt:30}},
|
||||
{isActive:true}
|
||||
]
|
||||
},
|
||||
{age:1,isActive:1}
|
||||
);
|
||||
|
||||
//Documentos cuya edad NO sea mayor que 30, cuyo campo isActive NO sea true y que ambos campos existan.
|
||||
|
||||
db.people.find(
|
||||
{
|
||||
$nor:
|
||||
[
|
||||
{age:{$gt:30}},
|
||||
{age:{$exists:false}},
|
||||
{isActive:true},
|
||||
{isActive:{$exists:false}}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
|
||||
```
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Двоичный файл не отображается.
|
@ -0,0 +1 @@
|
|||
{ "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "people.bios" } ] }
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"_id" : 6,
|
||||
"name" : {
|
||||
"first" : "Guido",
|
||||
"last" : "van Rossum"
|
||||
},
|
||||
"birth" : ISODate("1956-01-31T05:00:00Z"),
|
||||
"contribs" : [
|
||||
"Python"
|
||||
],
|
||||
"awards" : [
|
||||
{
|
||||
"award" : "Award for the Advancement of Free Software",
|
||||
"year" : 2001,
|
||||
"by" : "Free Software Foundation"
|
||||
},
|
||||
{
|
||||
"award" : "NLUUG Award",
|
||||
"year" : 2003,
|
||||
"by" : "NLUUG"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
## 05 update
|
||||
|
||||
## 05.1 update({query},{document},{options})
|
||||
|
||||
Se buscan el domuento y se **sustituye** por otro.
|
||||
Es una actualización por **reemplazo**
|
||||
|
||||
```javascript
|
||||
|
||||
// ACTUALIZAR UN PAIS
|
||||
db.countries.update({countryCode:'ES'},{
|
||||
"_id" : ObjectId("552b82d52f0abda151b2be0b"),
|
||||
"countryCode" : "ES",
|
||||
"countryName" : "España",
|
||||
"currencyCode" : "EUR",
|
||||
"population" : "46505963",
|
||||
"fipsCode" : "SP",
|
||||
"isoNumeric" : "724",
|
||||
"capital" : "Madrid",
|
||||
"continentName" : "Europe",
|
||||
"continent" : "EU",
|
||||
"areaInSqKm" : "504782.0",
|
||||
"languages" : "es-ES,ca,gl,eu,oc",
|
||||
"isoAlpha3" : "ESP",
|
||||
"geonameId" : "2510769"
|
||||
})
|
||||
// update countries where countryCode=='ES' SET (...)
|
||||
|
||||
// update multiple
|
||||
// Cuidado con _id repetidos!!!
|
||||
|
||||
// findAndModify
|
||||
db.collection.findAndModify({
|
||||
query: <document>, // aunque devuelva varios
|
||||
sort: <document>, // solo afecta al primero
|
||||
remove: <boolean>, // si lo quiero es borrar
|
||||
update: <document>, // el documento de sustitución
|
||||
new: <boolean>, // retorna el modificado
|
||||
fields: <document>,
|
||||
upsert: <boolean> // Inserta si no existe
|
||||
});
|
||||
|
||||
|
||||
|
||||
```
|
|
@ -0,0 +1,64 @@
|
|||
## 05 update
|
||||
|
||||
## 05.2 update({query},{modificators},{options})
|
||||
|
||||
Se busca el documento y se **opera** sobre el mismo
|
||||
|
||||
```javascript
|
||||
|
||||
//mongoimport --db geodata --collection countries2 --file countries_full.json --type json --jsonArray
|
||||
|
||||
// incrementales
|
||||
// AUMENTAR EL AREA DE UN PAIS
|
||||
db.countries2.update({cca2:'AW'},{$inc:{area:1}})
|
||||
db.countries2.find({cca2:'AW'})
|
||||
|
||||
// Y MODIFICAR SU POSICIÓN EN EL MAPA
|
||||
db.countries2.update({cca2:'AW'},{$inc:{'latlng.0':1}})
|
||||
db.countries2.find({cca2:'AW'})
|
||||
|
||||
// asignacion creación y borrado de valores modificando la estructura
|
||||
// CAMBIAR EL NOMBRE A UN PAIS
|
||||
db.countries2.update({'name.common':'Afghanistan'},{$set:{'name.common':'Aquinostan'}})
|
||||
db.countries2.find({'name.common':'Afghanistan'})
|
||||
db.countries2.find({'name.common':'Aquinostan'})
|
||||
|
||||
// AGREGARLE UN VALOR NUEVO
|
||||
db.countries2.update({'name.common':'Aquinostan'},{$set:{'terrorista':'BinLaden'}})
|
||||
db.countries2.find({'name.common':'Aquinostan'})
|
||||
db.countries2.find({'terrorista':/laden/i})
|
||||
|
||||
// ELIMINAR UNA CLAVE
|
||||
db.countries2.update({'name.common':'Aquinostan'},{$unset:{'terrorista':1}})
|
||||
|
||||
// AGREGAR UNA CLAVE COMPLEJA
|
||||
db.countries2.update({'name.common':'Aquinostan'},{$set:{organizacion:{nombre:'AlQaeda',lider:'BinLaden'}}})
|
||||
db.countries2.find({'organizacion.lider':/laden/i})
|
||||
|
||||
// RENOMBRAR UNA CLAVE
|
||||
db.countries2.update({'name.common':'Aquinostan'},{ $rename: { "organizacion.lider": "organizacion.jefe" } })
|
||||
db.countries2.find({'organizacion.jefe':/laden/i})
|
||||
|
||||
//
|
||||
// trabajo sobre arrays
|
||||
//
|
||||
|
||||
// AGREGAR UN ARRAY
|
||||
db.countries2.update({'name.common':'Spain'},{$set:{partidos:['PP', 'PSOE', 'IU', 'UPyD']}})
|
||||
|
||||
// AGREGAR UN ELEMENTO A UN ARRAY
|
||||
db.countries2.update({'name.common':'Spain'},{$push:{partidos:'Podemos'}})
|
||||
|
||||
// AGREGAR UN ARRAY A UN ARRAY
|
||||
db.countries2.update({'name.common':'Spain'},{$push:{partidos:{$each:['Ciudadanos', 'Vox']}}})
|
||||
|
||||
// ELIMINAR UN ELEMENTO DE UN ARRAY
|
||||
db.countries2.update({'name.common':'Spain'},{$pull:{partidos:'UPyD'}})
|
||||
|
||||
// ELIMINAR EL PRIMER ELEMENTO DE UN ARRAY
|
||||
db.countries2.update({'name.common':'Spain'},{$pop:{partidos:1}})
|
||||
|
||||
// ELIMINAR EL ULTIMO ELEMENTO DE UN ARRAY
|
||||
db.countries2.update({'name.common':'Spain'},{$pop:{partidos:-1}})
|
||||
db.countries2.find({'name.common':'Spain'})
|
||||
```
|
|
@ -0,0 +1,48 @@
|
|||
use control_caja
|
||||
|
||||
db.movimientos.drop()
|
||||
db.createCollection('movimientos')
|
||||
|
||||
//var movimiento = {
|
||||
// user: 'albertobasalo@agorabinaria.com',
|
||||
// tipo: 'Ingreso',
|
||||
// categoria: 'Nómina',
|
||||
// importe: 1200,
|
||||
// fecha: new Date(2015, 03, 06, 12, 00, 00, 000)
|
||||
//};
|
||||
//db.movimientos.insert(movimiento);
|
||||
|
||||
var nomina_alberto = {
|
||||
user: 'albertobasalo@agorabinaria.com',
|
||||
tipo: 'Ingreso',
|
||||
categoria: 'Nómina',
|
||||
importe: 1200,
|
||||
fecha: new Date(2015, 03, 01, 12,00, 00, 000)
|
||||
};
|
||||
db.movimientos.insert(nomina_alberto);
|
||||
var hipoteca_alberto = {
|
||||
user: 'albertobasalo@agorabinaria.com',
|
||||
tipo: 'Gasto',
|
||||
categoria: 'Hipoteca',
|
||||
importe: 400,
|
||||
fecha: new Date(2015, 03, 06, 12, 0, 00, 000)
|
||||
};
|
||||
db.movimientos.insert(hipoteca_alberto);
|
||||
var nomina_reinaldo = {
|
||||
user: 'reinaldo.aguilera@gmail.com',
|
||||
tipo: 'Ingreso',
|
||||
categoria: 'Nómina',
|
||||
importe: 1100,
|
||||
fecha: new Date(2015, 03, 02, 12, 0, 00, 000)
|
||||
};
|
||||
db.movimientos.insert(nomina_reinaldo);
|
||||
var hipoteca_reinaldo = {
|
||||
user: 'reinaldo.aguilera@gmail.com',
|
||||
tipo: 'Gasto',
|
||||
categoria: 'Hipoteca',
|
||||
importe: 450,
|
||||
fecha: new Date(2015, 03, 04, 12, 0, 00, 000)
|
||||
};
|
||||
db.movimientos.insert(hipoteca_reinaldo);
|
||||
|
||||
db.movimientos.find();
|
|
@ -0,0 +1,54 @@
|
|||
use control_caja
|
||||
|
||||
// busquedas
|
||||
var movimientos_alberto = db.movimientos.find({
|
||||
user: 'albertobasalo@agorabinaria.com'
|
||||
});
|
||||
|
||||
var nomina_alberto = db.movimientos.find({
|
||||
user: 'albertobasalo@agorabinaria.com',
|
||||
categoria: 'Nómina'
|
||||
});
|
||||
|
||||
var grandes_movimientos = db.movimientos.find({
|
||||
importe: {
|
||||
$gt: 1000
|
||||
}
|
||||
});
|
||||
|
||||
var alberto_or_grandes_movimientos = db.movimientos.find({
|
||||
$or: [{
|
||||
importe: {
|
||||
$gt: 1000
|
||||
}
|
||||
}, {
|
||||
user: 'albertobasalo@agorabinaria.com'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
var movimientos_parecidos = db.movimientos.find({
|
||||
user: /agorabinaria/
|
||||
});
|
||||
|
||||
var movimientos_parecidos = db.movimientos.find({
|
||||
user: /al/
|
||||
});
|
||||
|
||||
var movimientos_parecidos = db.movimientos.find({
|
||||
user: /^al/
|
||||
});
|
||||
|
||||
|
||||
var movimientos_ordenados = db.movimientos.find().sort({importe:1});
|
||||
|
||||
// proyecciones
|
||||
var movimientos_importes = db.movimientos.find({},{importe:1})
|
||||
var movimientos_importes_sin_clave = db.movimientos.find({},{importe:1, _id:0})
|
||||
|
||||
// limites y paginación
|
||||
db.movimientos.find().limit(2).skip(1)
|
||||
// cuenta
|
||||
db.movimientos.count()
|
||||
// distintos
|
||||
db.movimientos.distinct( "categoria" )
|
|
@ -0,0 +1,70 @@
|
|||
use control_caja
|
||||
|
||||
var subir_nomina_alberto = db.movimientos.update({
|
||||
user: 'albertobasalo@agorabinaria.com',
|
||||
categoria: 'Nómina'
|
||||
}, {
|
||||
$inc: {
|
||||
importe: 328
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var cambiar_hipoteca_alberto = db.movimientos.update({
|
||||
user: 'albertobasalo@agorabinaria.com',
|
||||
categoria: 'Hipoteca'
|
||||
}, {
|
||||
$set: {
|
||||
categoria: 'Alquiler'
|
||||
}
|
||||
});
|
||||
|
||||
var subir_gastos_abril = db.movimientos.update({
|
||||
tipo: 'Gasto',
|
||||
fecha: {
|
||||
$gte: new Date(2015, 03, 01, 12, 00, 00),
|
||||
$lt: new Date(2015, 04, 01, 12, 00, 00)
|
||||
}
|
||||
}, {
|
||||
$inc: {
|
||||
importe: 11
|
||||
}
|
||||
}, {
|
||||
multi: true
|
||||
});
|
||||
|
||||
// Cambiar un documento por otro
|
||||
var nomina_alberto = db.movimientos.update({
|
||||
user: 'albertobasalo@agorabinaria.com',
|
||||
categoria: 'Nómina'
|
||||
},{
|
||||
user: 'albertobasalo@agorabinaria.com',
|
||||
tipo: 'Ingreso',
|
||||
categoria: 'Nómina',
|
||||
importe: 1800,
|
||||
fecha: new Date(2015, 03, 01, 12,00, 00, 000)
|
||||
});
|
||||
// Peligro!!!!
|
||||
var nomina_alberto = db.movimientos.update({
|
||||
user: 'albertobasalo@agorabinaria.com',
|
||||
categoria: 'Nómina'
|
||||
},{
|
||||
importe: 1800,
|
||||
});
|
||||
|
||||
|
||||
// recuperación
|
||||
var nomina_alberto = {
|
||||
user: 'albertobasalo@agorabinaria.com',
|
||||
tipo: 'Ingreso',
|
||||
categoria: 'Nómina',
|
||||
importe: 1800,
|
||||
fecha: new Date(2015, 03, 01, 12,00, 00, 000)
|
||||
};
|
||||
db.movimientos.findAndModify({query:{_id: ObjectId("5522ac18dc9308d02d124fe5")},update:nomina_alberto});
|
||||
|
||||
|
||||
|
||||
// borrado
|
||||
//db.movimientos.remove({user: 'albertobasalo@agorabinaria.com'});
|
||||
//db.movimientos.remove({});
|
|
@ -0,0 +1,33 @@
|
|||
use control_caja
|
||||
|
||||
function azar(desde, hasta) {
|
||||
return Math.floor((Math.random() * hasta) + desde)
|
||||
}
|
||||
|
||||
function tipo() {
|
||||
if (azar(0, 10) > 4) {
|
||||
return 'Ingreso';
|
||||
} else {
|
||||
return 'Gasto';
|
||||
}
|
||||
}
|
||||
|
||||
function user() {
|
||||
if (azar(0, 10) > 4) {
|
||||
return 'albertobasalo@agorabinaria.com';
|
||||
} else {
|
||||
return 'reinaldo.aguilera@gmail.com';
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
var movimiento = {
|
||||
user: user();
|
||||
tipo: tipo(),
|
||||
importe: azar(100, 2500),
|
||||
fecha: new Date(2015, azar(0, 11), azar(1, 30), 12, 0, 0)
|
||||
};
|
||||
db.movimientos.insert(movimiento);
|
||||
}
|
||||
|
||||
db.movimientos.find();
|
|
@ -0,0 +1,45 @@
|
|||
#Comparción
|
||||
|
||||
## Inconvenientes
|
||||
- No Joins
|
||||
- No Transactions
|
||||
- No Integrity
|
||||
|
||||
## Ventajas
|
||||
- Velocidad
|
||||
- Flexibilidad
|
||||
- Escalabilidad
|
||||
|
||||
#Conceptos
|
||||
|
||||
## Física
|
||||
Server
|
||||
|
||||
Réplica
|
||||
|
||||
Shard
|
||||
|
||||
Database
|
||||
|
||||
|
||||
|
||||
## Lógica
|
||||
Database
|
||||
|
||||
Collection
|
||||
|
||||
Document
|
||||
|
||||
Property
|
||||
|
||||
Schemma(-less)
|
||||
|
||||
|
||||
#Comandos
|
||||
mongod --dbpath
|
||||
mongo
|
||||
|
||||
#GUI
|
||||
robomongo
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
angular.module('controlCajaApp', ['ui.router','ngCookies', 'ngResource', 'abFiltros','abDirectivas']);
|
||||
|
|
@ -1,35 +1,32 @@
|
|||
angular.module('controlCajaApp', ['ui.router','ngCookies', 'ngResource', 'abFiltros','abDirectivas']);
|
||||
|
||||
angular.module('controlCajaApp').config(function ($stateProvider,$locationProvider) {
|
||||
angular.module('controlCajaApp').config(function ($stateProvider) {
|
||||
$stateProvider
|
||||
.state('total', {
|
||||
url: '/',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'total.html'
|
||||
templateUrl: 'controlcaja/total.html'
|
||||
})
|
||||
.state('nuevo', {
|
||||
url: '/nuevo',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'nuevo.html'
|
||||
templateUrl: 'controlcaja/nuevo.html'
|
||||
})
|
||||
.state('lista', {
|
||||
url: '/lista',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'lista.html'
|
||||
templateUrl: 'controlcaja/lista.html'
|
||||
})
|
||||
.state('movimiento', {
|
||||
url: '/movimiento/:id',
|
||||
controller: 'MovimientoCtrl as vm',
|
||||
templateUrl: 'movimiento.html'
|
||||
templateUrl: 'movimiento/movimiento.html'
|
||||
})
|
||||
.state('registro', {
|
||||
url: '/registro',
|
||||
controller: 'RegistroCtrl as registro',
|
||||
templateUrl: 'registro.html'
|
||||
templateUrl: 'registro/registro.html'
|
||||
})
|
||||
.state('not-found', {
|
||||
url: '*path',
|
||||
controller: 'CajaCtrl as caja',
|
||||
templateUrl: 'total.html'
|
||||
templateUrl: '_comun/not-found.html'
|
||||
});
|
||||
});
|
|
@ -12,14 +12,14 @@
|
|||
restrict: 'AE',
|
||||
replace: 'true',
|
||||
transclude: true,
|
||||
templateUrl: '/tpl-cabecera.html'
|
||||
templateUrl: '/directivas/tpl-cabecera.html'
|
||||
};
|
||||
};
|
||||
|
||||
function filaMovimiento() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
templateUrl: '/tpl-fila-movimiento.html',
|
||||
templateUrl: '/directivas/tpl-fila-movimiento.html',
|
||||
scope: {
|
||||
movimientoplantilla: "=movimientodirectiva"
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
var valoracion = function () {
|
||||
return {
|
||||
restrict: 'AE',
|
||||
templateUrl: '/tpl-valoracion.html',
|
||||
templateUrl: '/directivas/valoracion/tpl-valoracion.html',
|
||||
scope: {
|
||||
valor: '=',
|
||||
max: '@',
|
|
@ -41,7 +41,9 @@
|
|||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-cookies.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-resource.min.js"></script>
|
||||
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js"></script>
|
||||
<!-- reorganización de referencias-->
|
||||
<script src="_comun/app.js"></script>
|
||||
<script src="_comun/states.js"></script>
|
||||
<script src="_comun/appHttpLog.js"></script>
|
||||
<script src="_comun/appSecurity.js"></script>
|
||||
<script src="registro/registroCtrl.js"></script>
|
|
@ -27,7 +27,7 @@
|
|||
</div>
|
||||
<!-- Button -->
|
||||
<div class="controls">
|
||||
<button class="btn btn-success" ng-click="registro.registrar()">Registro</button>
|
||||
<button class="btn btn-success" ng-click="registro.registrar()" name="registrar">Registro</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
|
@ -0,0 +1,10 @@
|
|||
"use strict";
|
||||
module.exports.routeMaestros = function (app) {
|
||||
app.get('/api/pub/maestros', function (req, res, next) {
|
||||
var maestros = {
|
||||
categoriasIngresos: ['Nómina', 'Ventas', 'Intereses Depósitos'],
|
||||
categoriasGastos: ['Hipotéca', 'Compras', 'Impuestos']
|
||||
};
|
||||
res.json(maestros);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
"use strict";
|
||||
var movimientosData = require('../data/movimientosData.js');
|
||||
|
||||
module.exports.routeMovimientos = function (app) {
|
||||
|
||||
app.route('/api/priv/movimientos')
|
||||
.get(function (req, res, next) {
|
||||
res.json(movimientosData.getMovimientos(req.usuario));
|
||||
})
|
||||
.post(function (req, res, next) {
|
||||
var movimiento = req.body;
|
||||
movimiento.usuario = req.usuario;
|
||||
movimientosData.postMovimiento(movimiento);
|
||||
res.status(200).send();
|
||||
});
|
||||
|
||||
app.get('/api/priv/movimientos/:id', function (req, res, next) {
|
||||
res.json(movimientosData.getMovimiento(req.params.id, req.usuario));
|
||||
});
|
||||
|
||||
app.get('/api/priv/total', function (req, res, next) {
|
||||
res.json(movimientosData.getTotalUsuario(req.usuario));
|
||||
});
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
"use strict";
|
||||
var seguridadData = require('../data/seguridadData.js');
|
||||
|
||||
module.exports.seguridad = function (app) {
|
||||
|
||||
app.use('/api/priv/', function (req, res, next) {
|
||||
var sessionId = req.get('sessionId');
|
||||
var sesion = seguridadData.getSesion(sessionId);
|
||||
if (sesion) {
|
||||
if (sesion.timeStamp) {
|
||||
req.usuario = sesion.email;
|
||||
next();
|
||||
} else {
|
||||
res.status(419).send('Sesión caducada');
|
||||
}
|
||||
} else {
|
||||
res.status(401).send('Credencial inválida');
|
||||
}
|
||||
});
|
||||
|
||||
// API - REST
|
||||
// SECURITY
|
||||
app.route('/api/usuarios')
|
||||
.post(function (req, res, next) {
|
||||
var usuario = req.body;
|
||||
seguridadData.posttingUsuario(usuario)
|
||||
.then(function (sesion) {
|
||||
if (sesion) {
|
||||
res.json(sesion);
|
||||
} else {
|
||||
res.status(409).send('email ' + usuario.email + ' ya registrado');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Gestión de sesiones: listado y login
|
||||
app.route('/api/sesiones')
|
||||
.post(function (req, res, next) {
|
||||
var usuario = req.body;
|
||||
seguridadData.posttingSesion(usuario)
|
||||
.then(function (sesion) {
|
||||
if (sesion) {
|
||||
res.json(sesion);
|
||||
} else {
|
||||
res.status(401).send('Credencial inválida');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
"use strict";
|
||||
var settings = require("./settings.js");
|
||||
var app = require('./express.js').configApp();
|
||||
console.log('ready... settings ok', settings);
|
||||
|
||||
require('./api/seguridadAPI.js').seguridad(app);
|
||||
require('./api/maestrosAPI.js').routeMaestros(app);
|
||||
require('./api/movimientosAPI.js').routeMovimientos(app);
|
||||
console.log('steady... routes OK');
|
||||
|
||||
app.listen(settings.port);
|
||||
console.log('go... listening on port: ' + settings.port);
|
|
@ -0,0 +1,73 @@
|
|||
var Q = require('q');
|
||||
var mondodb = require('mongodb');
|
||||
var MongoClient = mondodb.MongoClient;
|
||||
var mongoUrl = "mongodb://localhost:27017/control_caja";
|
||||
|
||||
exports.ObjectId = mondodb.ObjectID;
|
||||
exports.connecting = connecting;
|
||||
exports.finding = finding;
|
||||
exports.inserting = inserting;
|
||||
exports.updating = updating;
|
||||
|
||||
function connecting(mongoCol) {
|
||||
var deferred = Q.defer();
|
||||
MongoClient.connect(mongoUrl, function (err, db) {
|
||||
if (err) {
|
||||
callback2Promise(err, null, deferred);
|
||||
} else {
|
||||
callback2Promise(null, db.collection(mongoCol), deferred);
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function finding(mongoCol, query) {
|
||||
var deferred = Q.defer();
|
||||
connecting(mongoCol)
|
||||
.then(function (colDb) {
|
||||
colDb.find(query).toArray(function (err, result) {
|
||||
callback2Promise(err, result, deferred);
|
||||
});
|
||||
})
|
||||
.fail(function (err) {
|
||||
callback2Promise(err, result, deferred);
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function inserting(mongoCol, document) {
|
||||
var deferred = Q.defer();
|
||||
connecting(mongoCol)
|
||||
.then(function (colDb) {
|
||||
colDb.insert(document, function (err, result) {
|
||||
callback2Promise(err, result, deferred);
|
||||
});
|
||||
})
|
||||
.fail(function (err) {
|
||||
callback2Promise(err, result, deferred);
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function updating(mongoCol, query, document) {
|
||||
var deferred = Q.defer();
|
||||
connecting(mongoCol)
|
||||
.then(function (colDb) {
|
||||
colDb.update(query, document, function (err, result) {
|
||||
callback2Promise(err, result, deferred);
|
||||
});
|
||||
})
|
||||
.fail(function (err) {
|
||||
callback2Promise(err, result, deferred);
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function callback2Promise(err, result, deferred) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
deferred.reject(err);
|
||||
} else {
|
||||
deferred.resolve(result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
"use strict";
|
||||
var maxId = 0;
|
||||
var movimientos = [];
|
||||
var totales = [];
|
||||
|
||||
module.exports.getMovimientos = function (usuario) {
|
||||
var movimientosUsuario = movimientos.filter(function (m) {
|
||||
return m.usuario = usuario;
|
||||
});
|
||||
return movimientosUsuario;
|
||||
}
|
||||
|
||||
module.exports.getMovimiento = function (movId, usuario) {
|
||||
var movimientoBuscado = movimientos.filter(function (movimiento) {
|
||||
return movimiento.id == movId && movimiento.usuario == usuario;
|
||||
})[0];
|
||||
return movimientoBuscado;
|
||||
}
|
||||
|
||||
module.exports.getTotalUsuario = function (usuario) {
|
||||
var totalUsuario = getTotalUsuario(usuario);
|
||||
return totalUsuario;
|
||||
}
|
||||
|
||||
module.exports.postMovimiento = function (movimiento) {
|
||||
maxId++;
|
||||
movimiento.id = maxId;
|
||||
movimientos.push(movimiento);
|
||||
var totalUsuario = getTotalUsuario(movimiento.usuario);
|
||||
if (movimiento.tipo == 'Ingreso')
|
||||
totalUsuario.ingresos += movimiento.importe;
|
||||
else
|
||||
totalUsuario.gastos += movimiento.importe;
|
||||
return getMovimientosUsuario(movimiento.usuario);
|
||||
}
|
||||
|
||||
function getMovimientosUsuario(usuario) {
|
||||
var movimientosUsuario = movimientos.filter(function (m) {
|
||||
return m.usuario = usuario;
|
||||
});
|
||||
return movimientosUsuario;
|
||||
}
|
||||
|
||||
function getTotalUsuario(usuario) {
|
||||
if (usuario === undefined) return {};
|
||||
var totalUsuario = totales.filter(function (t) {
|
||||
return t.usuario == usuario;
|
||||
})[0];
|
||||
if (totalUsuario === undefined) {
|
||||
totalUsuario = {
|
||||
usuario: usuario,
|
||||
ingresos: 0,
|
||||
gastos: 0
|
||||
};
|
||||
totales.push(totalUsuario);
|
||||
}
|
||||
return totalUsuario;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
"use strict";
|
||||
var Q = require('q');
|
||||
var mongodb = require('./mongodb.js')
|
||||
var mongoCol = "usuarios"
|
||||
var sesiones = [];
|
||||
|
||||
module.exports.posttingUsuario = function (usuario) {
|
||||
var deferred = Q.defer();
|
||||
mongodb.finding(mongoCol, {
|
||||
email: email
|
||||
}).then(function (result) {
|
||||
if (result[0]) {
|
||||
console.log('email ya registrado:' + usuario.email);
|
||||
deferred.resolve(null);
|
||||
} else {
|
||||
console.log('registrado:' + usuario.email);
|
||||
mongodb.inserting(mongoCol, usuario)
|
||||
deferred.resolve(newSession(usuario.email));
|
||||
}
|
||||
})
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
module.exports.posttingSesion = function (usuario) {
|
||||
var deferred = Q.defer();
|
||||
mongodb.finding(mongoCol, {
|
||||
email: email,
|
||||
password: password
|
||||
}).then(function (result) {
|
||||
if (result[0]) {
|
||||
console.log('aceptado:' + usuario.email);
|
||||
deferred.resolve(newSession(usuario.email));
|
||||
} else {
|
||||
console.log('Credencial inválida:' + usuario.email);
|
||||
deferred.resolve(null);
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
module.exports.getSesion = function (sessionId) {
|
||||
var sesion = getSesion(sessionId);
|
||||
if (sesion) {
|
||||
if (esSesionValida(sesion)) {
|
||||
sesion.timeStamp = new Date();
|
||||
return sesion;
|
||||
} else {
|
||||
console.log('Sesión caducada:' + JSON.stringify(sesion));
|
||||
sesion.timeStamp = null;
|
||||
return sesion;
|
||||
}
|
||||
} else {
|
||||
console.log('Credencial inválida:' + sessionId);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getSesion(sessionId) {
|
||||
return sesiones.filter(function (s) {
|
||||
return s.sessionId == sessionId;
|
||||
})[0]
|
||||
}
|
||||
|
||||
function esSesionValida(sesion) {
|
||||
return (new Date() - sesion.timeStamp) < 20 * 60 * 1000;
|
||||
}
|
||||
|
||||
function newSession(email) {
|
||||
var sessionId = Math.random() * (88888) + 11111;
|
||||
var timeStamp = new Date();
|
||||
sesiones.push({
|
||||
sessionId: sessionId,
|
||||
email: email,
|
||||
timeStamp: timeStamp
|
||||
});
|
||||
return sessionId;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
"use strict";
|
||||
module.exports.configApp = function () {
|
||||
|
||||
var express = require('express');
|
||||
var bodyParser = require('body-parser');
|
||||
|
||||
var app = express();
|
||||
|
||||
app.use(bodyParser.urlencoded({
|
||||
extended: true
|
||||
}));
|
||||
app.use(bodyParser.json());
|
||||
app.use(express.static(__dirname + './../client'));
|
||||
console.log("bodyParser y servidor de ficheros estáticos en uso");
|
||||
|
||||
app.use(function (peticion, respuesta, siguiente) {
|
||||
console.log("recibida petición: " + peticion.url);
|
||||
if (peticion.body && Object.keys(peticion.body).length > 0) {
|
||||
console.log("body: " + JSON.stringify(peticion.body));
|
||||
}
|
||||
siguiente();
|
||||
});
|
||||
|
||||
return app;
|
||||
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче