thinkjs/coverage.html
2014-07-01 13:31:37 +08:00

354 lines
856 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html><head><title>Coverage</title><script>
headings = [];
onload = function(){
headings = document.querySelectorAll('h2');
};
onscroll = function(e){
var heading = find(window.scrollY);
if (!heading) return;
var links = document.querySelectorAll('#menu a')
, link;
for (var i = 0, len = links.length; i < len; ++i) {
link = links[i];
link.className = link.getAttribute('href') == '#' + heading.id
? 'active'
: '';
}
};
function find(y) {
var i = headings.length
, heading;
while (i--) {
heading = headings[i];
if (y >= heading.offsetTop) {
return heading;
}
}
}
</script>
<style>
body {
font: 14px/1.6 "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: 0;
color: #2C2C2C;
border-top: 2px solid #ddd;
}
#coverage {
padding: 60px;
}
h1 a {
color: inherit;
font-weight: inherit;
}
h1 a:hover {
text-decoration: none;
}
.onload h1 {
opacity: 1;
}
h2 {
width: 80%;
margin-top: 80px;
margin-bottom: 0;
font-weight: 100;
letter-spacing: 1px;
border-bottom: 1px solid #eee;
}
a {
color: #8A6343;
font-weight: bold;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
ul {
margin-top: 20px;
padding: 0 15px;
width: 100%;
}
ul li {
float: left;
width: 40%;
margin-top: 5px;
margin-right: 60px;
list-style: none;
border-bottom: 1px solid #eee;
padding: 5px 0;
font-size: 12px;
}
ul::after {
content: '.';
height: 0;
display: block;
visibility: hidden;
clear: both;
}
code {
font: 12px monaco, monospace;
}
pre {
margin: 30px;
padding: 30px;
border: 1px solid #eee;
border-bottom-color: #ddd;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
-webkit-box-shadow: inset 0 0 10px #eee;
-moz-box-shadow: inset 0 0 10px #eee;
box-shadow: inset 0 0 10px #eee;
overflow-x: auto;
}
img {
margin: 30px;
padding: 1px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
-webkit-box-shadow: 0 3px 10px #dedede, 0 1px 5px #888;
-moz-box-shadow: 0 3px 10px #dedede, 0 1px 5px #888;
box-shadow: 0 3px 10px #dedede, 0 1px 5px #888;
max-width: 100%;
}
footer {
background: #eee;
width: 100%;
padding: 50px 0;
text-align: right;
border-top: 1px solid #ddd;
}
footer span {
display: block;
margin-right: 30px;
color: #888;
font-size: 12px;
}
#menu {
position: fixed;
font-size: 12px;
overflow-y: auto;
top: 0;
right: 0;
margin: 0;
height: 100%;
padding: 15px 0;
text-align: right;
border-left: 1px solid #eee;
-moz-box-shadow: 0 0 2px #888
, inset 5px 0 20px rgba(0,0,0,.5)
, inset 5px 0 3px rgba(0,0,0,.3);
-webkit-box-shadow: 0 0 2px #888
, inset 5px 0 20px rgba(0,0,0,.5)
, inset 5px 0 3px rgba(0,0,0,.3);
box-shadow: 0 0 2px #888
, inset 5px 0 20px rgba(0,0,0,.5)
, inset 5px 0 3px rgba(0,0,0,.3);
-webkit-font-smoothing: antialiased;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGYAAABmCAMAAAAOARRQAAABelBMVEUjJSU6OzshIyM5OjoqKy02NjgsLS01NTYjJCUzNTUgISMlJSc0NTUvMDA6PDwlJyg1NjYoKis2NjYrLS02ODkpKyw0NDYrLC04ODovLzA4Ojo0NDUtLy86OjwjIyU4OTosLS82ODgtLS8hIyQvMTEnKCooKSsrKy0qLCwkJSUnKCkrLCwpKiwwMjIxMzMqLC0tLS0pKissLC00NTYwMDIwMTQpKysoKSovMDEtLzA2OTkxMzUrKywvLy8qKyszNTY5OzsqKiw6OjswMDExNDUoKiozNDUvMDIyNDY1Njg2Njk5OTozMzU0NjY4ODkiIyUiIyQ4OTkuMDEmKCowMjQwMTErLS4qKywwMTMhIiMpKiopKy0tLjAkJScxNDQvLzExNDYyNDQmKCk5OTslJig5OjskJSYxMzQrLS8gISIwMTIoKCk1NTUlJSUnJygwMDA4ODgiIiMhISI8PDw6Ojo5OTkpKSojIyQ7OzsyMjIpKSssLCw6Ozw1NjlrfLakAAAg2UlEQVR42jR6i3ea6rYvPgANIAhVXh8WvkQlioUiFlFcBtAmoiRNdzxqu9p0J7vrdK29zuPeex77nnvO/35n1r1ndHRktI0jTOacv/l7lCBK5UqVpOha/YxmWK7BC4TQFKVXrbYsnimqxuuMVlOQ0XltWjUdCwRJ1M+tC1KudOs9q6+da2adUewG0SC0SwELfHtgDds93VEuydEbl3QMWeNoYkR7b/0x1ZRobGI3mLwzAhePqTAwhg6aogjNsGy7/jwQ4rkdqe7CWLxF8k9LfMVFyRS7VJqtkrW8Vt/bkR8FZJao16ipknbC3Yw2lM7laO6HBEOadEZ2tpf65c4v8e3u7FyU6qbiNNyCuzXZ6pawgnwgmrpTT/Q7w2EZmiIJ0dzWDI7mhQ80IfRnMu2kzA5r5r1pIFoia+/d93HRYp1GV8TbrkWoU/+jdI0Ff6yGwTjT1Hn8J+8m1rKpGiYPuNiHnMtNMIv+zpsk84MYTNW1/+DpwXLvckdOCMYowVNPREe0QlM8xRHXXFhcNDzupwsSmb5pH+0t0RP2Qk+QtI7F1Qm6JRC6ZPBtPq/dq/kH+jxtCljn9TIpW6rQIgmSVyj6lPICIw4N/taka41PFUInth0je9+jO6Kt1G4/a7V2LEgG02B0pHVuCZrgltSKMuIl5SyufUv9mYuQi+mFgzbBEtFo2g+Dh4sSTrLNu8JPh00sQydpb00tqXBvqRN7Q7kqzcnIxCGnvZt/WmJacoOEO6Dcn8Qre03pOCSQxbMOXUuDNx9SxuLz4W1I18gvjViQ67zV0rxdWL8Te/TQkuo8STS41DR48W7L6YP2uWIqiUV8rd6Gbf/rnegKZeG8TpAM6afhGze9JAOxbLjsnUXEbrZ9vLYd7MT32cPF5mKKxmjy7huaoD9n62GOxni3iIJwv0IzZAZjdZkUtolCNLVfYZNaquFjGszVVf+J0vrz4CawoKdHnOzb0NMH7CDBOybfYNJ4rfeMyFNjkFYVTzMFs87rnPGXLUOeNKRVc0LnU7/UIgelzsy3CMuth0YfvnY0wsD3vODUL3eJcKqHQpm8yM3XZQWJxO6Un9iYloyyLpOwN2obHy6W6gbpcb44XmyC+mg+itAcaprGcrwZCqMj/GmtKn0zPvpTz/Cv1dw21XwP3cRupg3H3MF/S71eTKj1YrdwKdc2Mw0fRmb2sFf8lW3aU6JbIZSEPqvXvjM7G/aApyXlXeqKfMq0g/Su3rUGJPSPrtGElgknrZM3xUXqsAP6zMCNVn5u8aJnSNpJv2uru7t2jfRziW2+GuhqfldUNbPk71olwo+46ePUo1U3WKk/e5YK07F/wGRgcpODmQnIlVeHCWBE4puBi2jq28UKpqiN1/4UOrGz59TNYrrQHtd+11sG40BGD+pXdelNqGOg4NXe8W4eacJV/NS9/2Umtym6WQqveqR9xdCMElpxnbkalM4Vf9uaEcWZaKdyibEIjWKxJZPN95niCL3GiaXyssIrHxoLkqkzLCXULN46/f2h3tQJgyip+Tk9EAjJ9aJshq7t8X45aowSKspMSvPf7r9R8yxNptIaHS5ozuEm6luPDApugyNP8OaqiQ4BjaequXA54SLC83eHIY2r+CZp4409Xqw8Aa2oI7XkCrQi+in0w5AqF/kLNrcUz+qkl/lAobY1jSnx5OJNhyXIz3qfNFlXc0TKaglNwdWkWYt9QQ1Kr6W8zue21iNrdJk+N5oCr2O9nEtWKC7IS5J/zdDEYrmnAYfg6agCy+qcgz7ZofeDc4PbUWSvkshWuAc7OjiUyLkj+RAtdlwXJcjxdpkTTHDhK8lBCi8+JtvDVL1W6elmOM++YS0LuSlaP1oUvAeiW3cFnvTr8EbTz1tsSMYdGeZe40sRWu5uAfj7q+ZoKv2FNQ0p5XY1lmlcigHZqTPpabufEVrNuNPi165w3uCVQJHyJqmSJ7ZHnguqwtCmwViIJijj04ba2JNYtB+yORf5gg1/9t9iw4vUpeqiunSAbf+IBdj/b+iG2qrHvuNP0Vd/+ThVZT/lrvHYjjgDbbyxaqgHNM2uhxa1GW3UedZYhMMwM4mQhltouK+IV4NdbIQNM+8Yv311RZk9kT4tiYR4LkyFcuPpdcjuhUuFqBAWRZa11lcZ3gEBlXywsNhrt+plISZP5DlsV9l4EgY6J3yZPTUcMrgaWAT3oI79eSbGEbcJpr6BD8kyDiVt+G0/hXosQN4NFXKlfWIfsIs0BHODVok1/IGnKFHJYIquh8Xo+2+bkQNTGgWmN/fZ0Y33LSj6lr1GyV7mWIKg7ZTRZPGuhF/zjRNcQ1UPtSYgnWQxSs0yrVhwNDcdGMNSNe2JT3WuzbAM3HykyAajS3Uphf6STKEqxLas9EnmnhA/lyj9Uj+JoY7SVgVmGLl46Rm2u98sbkap2lzAdKBG4r6LgulQOSSjQv1GWdQ0jtDUK/mAaqM1Uqjpu4k3Rvfvxv7YTxLSK+wN3E5jVIzmF23uZ7hiH/sVP49D7tvoKp4S8b1LuvRlivVB/algbhcFITYVXvDpLzpDfplR2uD5V4XJFxpjmIpLc9Y5sB2TpBRix7Bme6GZIq+06v3XzNeTcA4obQIKxrnT4C2JpOqD92dbmSX8MGazly5EsZVMvSU1f4RZwyu8iQXbVdeLlZrjuTT1jrY1uk5c7iZ7RsvhhluqAkq4JpVQAg7RJFtSu+xgJ8Pv6O1j5DkLxT8mkbfyRW5DrQmG7hiDIjCgBsADbjuof6YHLGeV6a5Q1Smx9joUXPpdaaDx97A/Wq00oJkdR7ZYuQRfS533JtxO1erduqWOYIt3wh0wpbLuCNIYkwxbswbikCUu2CDCS+Q+7rgVtfRcm+SOcdKPRlZ/rE7wNVUEE39KTS5uvUKN1PUnkloPkyzhyGQ8qkouEjJ3H/VXdqG6asSRiw3ecMlBvDDt8dDhBHXMwZ2Cajzjr7/76T+IavqPYvz6r7//E/3X3+N//h/0QozbjPgPiir69P/8X3/9F/yv8b/827/++98WItPu5/Hvwd8YPf5bp/2/lX/T/+Of/0MJ/lYTa+L/Ef+d9vN/3/2T6P/+jyTzu/evf6U7vxN7B6pJkRtAF6jUr8I+P8RsP/ptGhfqFk+pQ/DgAy6NJtRYJdXmp4gK7WLqLKJ+MaKhGjOojvL+SnIWrkpy0SLHDe4QuyNzaEA15mLMCcmE8Em+4HdOihW4/ZWuppJEmzeAwcDtv7MuLc9y2V5atvxXNe3S4DUMt5/Qy2LM9kSYKiVWBuKlfp4nxTntpuW03JbIlkiRvBXmT23g1I2OYe6IizUHPIq6zm6mbfsbteKmi/sg9J+ocQBMctGFO7iljo8TPN+z3jxw4do+ZwfqoR9dkNTKHyM305GpTkfhcHexVkPVGEbUOjuo9f0UMPHBFlGEx0SLvJvVRKTwW7PSew5oPme+E42+frJa9cGt2njS3dK5kIif2eYbhuSEQXEqMVfUjhGIuin0G0/W5ezJyJQy3SpMLai4M0JUWb5u1k9tny5bd1pPwYBpQuDCXZl62xg4CdVEAtflXHs6JKmP/pH6mOl796Lgopj0o8d5kKh00hxG3OSdEE/QBo9Hgr8JJqAeLDwJohG5j/DGh61Rc/+tf22/8kEnxHNCEjo0ElvvGfESZkqmz2BDcKV1H1buSkhkdg7p1IMGs2s17nYjpblrWuE2K9WEO/hcRp5e9oOF/QBmOaDtgil+oaU6szPrdwW65fOB0KUTsVUn7LFU7J8e6cxJIl9+FHw5MQMzuQJ+4oxMH3iW/5GK+hWuG0T+gTLs+fAjdtUd58TmIUq04EeyRCYCjkldow234aIgR5bqwrtZosZ+6YEqAmDqatJ9lWasz4IquKALPtd92hGI3Z2BdzzZue+REl1Om4DIWD+RrtUTOJLI+S0jHowXXdAxsGLSd40zYNuEUlOGhrwL6c7tcOtUOvpJCP7QBQS19H+GvZn05ewjlVLz+IGKoC9TyfQjLMBNmXCuqqtTdOSukZW48B0HqgSTCBrBnlFvF4CG2Su7yFzqmJFURK3UmTT3ru050r0ptUpMilYnBJWfl2Bv6kPlUuE1kxxpdzui9AubsR2N2boVSu81OulAwBqoSr1LZ0LLYOomyZHmjqnXlP72s8LnDouEJjtodBvdHaG1jMySYO7crWd90MpCRyCG14vb5IE7Arupw/y/RcCm/Tm3zK6zYj8PYNaGldiUfkB/LHWcmf2lVM+mwyU27a0qq2tscrQ/vzBjN26DnntIrOyGizzXK35yKQdYnUABkyN4saz3WD/viF+eCcsXnIajdWYJWaYHRstIis9CS+tqnFGmz2j5uzfr3Z4prqgK4XOT/PyftvjZqIm8lhkfxJ7Ol3CJF1piYBGAG8wtAk56Drw1YwmOpcz+NdfkSpSLplRXLXHL0Rquj6YW/gabqgK7Dgr6NwtH0B/AN7XrN+MVJ6AmXmUuqmQulrNNYPmH0RoDogydOKLo/QbfYNARSQQKISRCzRXU+q9WWJFL3LZW6u34CkeG97xC0NNGaJ0bvK6SnZS3zPskr5EtuCgjMWR5o2x5BqhKmDWJPRe7JMEOyRb5uUKlHaGVtq5ivSOaSliSXp9SQm2qk8MRJh10MAp9QQ2H5t59J8rjiwSZtoIfMGjlLPVNdYl/LBR0AO6WLGDmkLkIPRE45Y9MftdAK/yNu1Hn6tzOQTesgQ+8fSzB19wO91vCnO23vOWQdwJ63SJrYjdfKFW6W281PKs2k8iT9ai1cgJ4sa3xqdvmtxR8/+D1B8AKc2u+6JftryRhMWSQtoSBgIyyQGyxcnELuAasXN12oSriU4RMz1DD6RL0TSV+om7i1Yt+jEE/jnawM8cX/UhN4nkiv/w9eALrzNhXuQfOzFL0Fi6SjF7/4Qn8rLYBoa85cvgAnkCEBP+HPbEnquVXCZsMS/yzYw2Vru60P/+nJPYKkzZFjmbykzUoEqV836T5q3fP/L383dF82tx18/AZgZczMAgyeWYKmSZIqtHL+e+O4ZRcq9VI3g/qPeCoiK4pcgEqdbS0S/Be54sbVQOuJVPNBblIghzeasNu7h/g+Sz1IdhI5lCwq1nUb3Ji4OCIcqQZqtqJ5w7rXrg/DA9IgVmEGhDgGecEwnCTHffXcXs0V3OCEVzYDKS1vp/oX+ng+6XVU86UjA6FMO2RXOOOrqY1GgPvrAk9HV/BXtCu5RuwF8qgdGDLsBcui4E33ymdBip1X8uKyhIWT8qNRDsXz+gvO9UiEC0d8RG4Tf2x8H4slljgHtCBcxHLTWOYJm5H/fCPCzOgf9qgOUxTRZ0Pc6ha5yLuLVT9ntvIa6gacE99mCovdUumTQdRP4RPsS9129eEe2uSvvGh0bV4Y3QPPhPZMqhZWSMa5R0Hc1SGO4IVOQc0FrirlibTVfKRrYkD8kz3b+X65/QkUNaZdrdl3mCap0Hf3YcCw/LiouJYNbqz88UqeDYv93yO7vvXtgl4XCyAO4ODkY6W+83+LZU//p3/zXNGGrUKClCiOnL27iJZbNWDF02XXAOeFlB7IaADoMH1Yqr+UP9biyZDEa/iJt4MDeIz6GKTdLVBfWGVtRN4fdT2rgReX8UXwF2zOrradm4J0nyTgdPnai3RvzpZvCKDUqjOwD/QA6EDaMCLewX6QWYVnHY1sx1bd8ovYnPm1ZvPH+rE20lWjOCnZ66/xDt0QAl15FjfBcZp+i9OU0RNPQ0t3x2pSNWo8eiYudwsnuP1Hq6iH1LJCJynkYsfgJ0p3pF6SoQk2l+jqE8CPk+ziGJRSKjs+W5AO185umPdkYzlK4wl7TC9NxyyDP7ZoyYVoXiuS6SjnInlLWrwz1i8bGTKXX0AVQWkSfIlglW3zRJRJ8bg5VgE6ZEnqNu9B++0GNQvDQJvFize4ESNKBJP+8vA3LM4AX5SIBq08Mob+7QMTCZx4nwP/64+4BnlZC+8WtlP/CXw6t1PwMwkJ3jhP1FiXLhDF/3I6FGUzO2DSi9ABxKyyL9paZxSEz40ZCPQToDAJu1959k7QdbVxgB4icsu2s4zsTPJhcEDo+N1GX4zSk/wriRh8AqwL62972i9HJHd1ydaLXVzvKvOfGGw5RVcUVMiKXFH4APdkQU/dc5BX0YfKTNZYXCW9mb8bc8mufoQP6BbdQmT99ZjoYfr/go4TgQX9IDgztim7wyFeGMfbNaeqj8Dzs38pgcqwSv2hbqB3oSGKWKy+sesY7p57wAHldqE6NDudk/W7s/zjrK4rZFlFvaGxnSZdHbc1y47qDN6xkoK8O3bfr2j41dlJZ71rB4dlDqapPFa8N6xBrprUdtenUCHwxKNhw1uuTBh+9uU45k4REpQABN2bAO9DSLqoIL26gNroWgup5pUMxHUNSq4Gyz47vBPvilpo5f9OYI2ddAqTqmnxXERxQJ3UK8fHbVE9HagHi3+tqNRoNsArdmAxHA5LwtQo9ZAaNKUTljnokljo2x8scqVpEEIPc01fPCdHOCg0DeWBz8D5TVAAfx8aRH5X2ZYNI3ebKDZdeJ+oBDAxmRqJ30Eh2/DaeAy5diVNMpEDmXiPDsGTzBLXy8eVDdJoIafgx/gxMyQi454QrW56nCyeELgSuNNEmYkflF+t3CZQOVRWjKhIuCclmQSlAXT3+4JGG75B4t/5hQ+ldMP4LsAW6z3XmU6IJJwpnGVnsgUZhoY1fZlwTR8wSU7xRejf2uCx9Z5trVTRRJP9KnEb134dEieil6eCOGWgboI7xsqsqM99jfJLTePjygKlH2CVxxsse9QRzTBFjD/Kjqitr/CCTBt/SJ6nLxz7cKP9pFqBpp0lN5y+adKNsZjrPuroemZauH9aTTFD3EKHW8S55XBLFQAt1jgxTQCTwxmx/JyfsZDN1RroN3VaxpSenpIX7K+ZbL8VdlQDcI4Cbzg3QJLa9yVqNxUelu+EtxLVqeekaAvSJkO6sSVqbUajxqhKshNpvZqoeApF0k/0P0ikkwUcbdwc4A1ejN7Oo0O15kG7hTMoK3hZRBCX7YYeLW0wvcXx/18n/u37yLgzBYVBUvORGli+sfRcX/74uD6P4hq+7xu54TlWJLFzT63uwUDwuEDdOjJQqx7JV+ZjaEAPi7t0MMrR4Q8Rkf18uxD6RK0RKh0hL8YU+DeL97i4pa5ZSyAfXKwZRS/8gXcxdZXm62RBDj8U3sN8x95b5PpPs/mCBKYvpaA50pN5Ct/499AFTtwQ5vgeSh+NHrKIi4NVpwM/XzRaNfJD856lPE6M21zWPguFsH7jbLVyEDfRmt4VwrhCJ5VTYmcSPfGgO5clfN+vbaDZ7sakU5+2vZ2WCDY031NxJarVytfDDVtiafcTGO2rJ/taoL3zChN2qmjxofczTOYQPPVQPh0JVtYgdUQINcSiNEEy58UdYXX1MpWUCEBx7LbcGtAm8XWRQTVOaoV3ySri4RShhs/B/0m4jX6OAwXOvcA09bNSG4czEGv/Wey6V/jbTCNTW6awXdNTcA1GsPe1E9fZdGl7R0vyoVpIdJtfC6d32NNErrvq/R+d65VG+YOwRXppXxOCYyGNSf1K3x6VxAW/vtz4EC1SgCOSPdN62sLsoIzuDfg8GwZAbquVO8HIuFP/ToVoeUB7nnwMF35a1wK1tI6fkrqFKhQdeJpwyls0pIy8AZde3/6LUUbFaYJthyUJSU/kqDXTLQElnn0Jr4B2RVghNrmNmoEn7pXIeshPguXVsvwoTdmClq49JJU3LWhHyWTrJL9bRP6VKv3tZoA/th77p5Jw++OEENvyvWy/pNeExiDUVQaXIRGh8xySZTI36yueFaSXo1uJY0RnXYgEOoWWOJHeaVuX/bGNhHsh2yinznl/++NJcE9j6fBPRcBdq9hb8awNw8U7Bl6GM7x69EDOIIbX/npZ++amlHR9L/35mE/2Ss4gb0xCcY4VyTFLRE796vHysLAamqcyO+aFQyJIDBNslbH2/MrAvZiSEIedc/cqjmv4fbda2pXbv+F5a2szSsdkm9noiNURXt8edUhGUF6fSZWd1IJaXKFwD+49R6eCXD4Bkef7j9tRtNMVgW8BhRz/Qpy1TmeYk0doyjZoJSbePOReVHgkFsCFuQJ+Lgc4BxeAsK/cOiNDRmdNw0ctYhn/nQ498dYI5znzGLoJi1rav7Cn88rL3wLePVtDK5gl77Tki3gHEsIAQ2+IKgarj7Y8W1IQzV5V9N+0TjLqbg68WfKcOmBCOj3JkwJhVIkwDhc+JorXuZEPMEh0vvH3x7iqf+VAwXgd4diZiaJD1zHL9Snx6Wfg4IugreyhabQkcir+y5XgDtdx3Avs7lkeeCBwDvZoTUCXx5QrZkcEqWfYEiEYRs/EphmRALSNGR1Iclgdr5VFoELpzF4++f35w3/j0t5ucW3n2ch4PQCLuUXupsPRR7UA5FjSKrMtPcKAZJfagO4lGE7FH3YKMjorpK0ZxAv+i2JkJhtAMWWWFej4RhPR/cJ3DxwocCvXDi4SGZU4cu+K32XndiFWgopAl+0GApcwf1XvymJcFs39jExIBO4yUjU9MExBLQYc9H+W7+IgdESPRpciT+rKZPebVtaVq+1GYO/5xTAL3HASjNTGIgMvdjWbgc7JvdE1zIFpuC0U9ESiZyzBixzxWxj4Kwh8My34q+FK3KNLtmsA1qyrmKSNQOXCPUZd+ONelBTvFoUI/CYsqa/RhtKiyMf2CgSFqEPk59Y3uqnlZ8gFpswfSYyko23yVZYxzKGxGm49Zqxg1l8oz5Ra9XaRwHkuxepmgyhm0SoNy2KlbcEqK+9QqS9PNx9Ihm9U7gsR55SSJ1FBDNnkuWKxIZ0SDpXuOGwZdoUbOMDPHP4vBAgz2VlSEJAHZGJVbYIg7l/FO5KfIVvxC8pPPxMGcNMoevFDeStt2iqztE10n2TA4dgJH76YS9HDhKHD3iCx6ieFX84BAI3QQnngh76f5ruPQVbr5qZmck/5UjDc26lfrOvUBWy0Ogl8bCoOkMOns81TnC3cuUS9KW8+9A+fe3XYZOFUPG1u5epSSmDLw0s5s2F0W30ANeo+zJkJQz9SPZgzwYpEoktofhGVfmLOAB20boCbW1QWq/NpET/hnMecw/uSyAH4NJc3ECOU4nnkK1fj3S/i5dwb3R7k00AqQQUwt7Ie1qV0aY/VQX0J8hLPy7eBNXMHYZYDNxHZ2Qh6AuXJxq+AeRec/Q+JLhZV6hpXwQEzw7bf5v9uUf2vpq3qlhmy0IIGTkwYdCfSAFmqbdo+3XvDTDjFJde0mbeQLcn2n31xaAqJ0ixO/CLsT4I4G4DoncVTgRGNBtsCcjISWT+oeXZ4Iedw/8OsJI1aPnNKLX/60VvcZb94uasRxCkqlPQ11u1Sa2hHvB80WQENxVyzjns0/PiEByyil21Te6oisk3mNCEMrhouCFO3yEZTHHOCMy9eb/4Tmi8cVf3Lf7P53SY2hX3PSN033As3ETIMLHWumWEO9JXHA2y2SIBlIPpLGG2qvNsCIlIr+B1SWAqRKm2w6Blf7U+zCSBwJrfHG5i8J5Gax/cVonMlon7aHJX/gSvucIncRP93XCqkv7D8IFKFsLiBgHqUpXhE3pYjEcV1dk/JD9zFVCfEaQIVX8Jmfz7IIofcBKQ4OaG+C3xC2veX9CD+iAFXDNaGg9eTVxvkbJRJlW4Nk9Wk13kn696jWppRDe/8pDrYMO9ZyxZ98ReKSz9kWKLLyk2zCZgAniCkLJVX3n1M9DYbomyahWiv/KixRIV9hj/oFz87I+HLznbPTjpa+D+bZQnMuRsljTpv90vQUt/pK7jCFnA30B/jtroSF2/m/gpWn1aQs5WeA6ghzF8SdqWI20fghdSeDOCSCmLgTkfaGgGDmw7nHFkRzGtag57IHS2na06I+gzEphXo1w/Zx2BM/jKL2nZoFjHggtFQjYi8nSVRSXIE58RPbBObXk7uuIL9+rs/5Zo7suJInEUxgsiZZAWS25iBtpEiZeBgDtghEoAE0sjcayNq85M4tbu/LF5h51335PsGzQ09O875+vUS89lkWMyNOFoip2PuyWyMP/iU2XIZdfCCJNDjebDoBLQdpy7QQZC7s9c0wjHJervQNDu2jWzBW5MSAJMr7bP+Iv92BkS/GGgzjEn7MF1IRKFwwzbjbS4/slGOmhx9cZrFu7HSEefojNv3r0UaKfKOWzXsq1zEugbzlMDFsacRJJI/iJlK3vtkZ+PLZIVMFlKA32wbq2Kd5T0uCLZ1CPkAfCdzkz2EYscjDcZq2AWfziN2covN4kXE1lQXPPLTNM1xx3tbiepcO/t3SWm4w87qfh99SL0ZnY+LKFPLPeXVM2mIIoVWt+9Nk0I7nY4O79iGYqxZ8RVz289an6NVdJWnSKZvJQCAuHNiVaDxPAFoH392t9wot5t0/qmU95eEWNbU2udUW5sN9JVqcYlvAIfLeYC33oUzzxZgSktsv21mA7Uly1FA5VnoJFh6N244Wmv3YJGFv/TCPryaw+ZORlpZjQdq/2DYXr3EZskfed0G61P09ipTKmlTQ1067Rg5+PAk5FlQ9e0SWbGf2B/08kqymOTMVOznsALHHNFH4LFRKl2F/NOiYFl9khNHnSu9Ak5sq26Ynl/i2fdTle29Y1ugqmR5Yj4YT9pvslFyYCbw0mNFr5rVQm1LvkG27QMq9ph3t8fmn6r6SQ4oSbr5tz+J1kIawGzDxb6VYOvvWhobDTXfBeNv3b4aNm5XUinsCGqG2q/45m3+LoCOsddFceYhRx1Tsss9PLdPfJdErFMjYd3gddjiP0+XQjcRadZP6bwNLySvunFf20Czy6JqdEW2a96KxdYdOryBv1BjbuUq2yCHeh+6sk7fGmmPi50pe/1l5TyPe5oHW9oPnhPswLyf2TFDdCyYlhwBCstv5C1HwlW7xWoGT9XZt4qVj5WryLPLLD6h/5cMLEjWzgCeAIKNsLak92aBqBsHl4AJwl2N4jfvbSkBExGimv0nFvv09uDScQbjx+w4kPQjgjlW+g9ws9VEJvI2k8N6XxVu0uIwovgTFdunG24gBtaDi+y1YLQwZ8mwbip5fVlO3k0n0AEr/ETbtu8Vjkm+nNSiEb7X/3fMjBL5A8PdgG+/FnbexbFFExmEfetXAnisEKy5z44WVPpQZjSy/jzeGn4yDRsFGqhh87QPaDBWhlo37IFbe/C0xynS91d2tP/AJoJS0sVF6iwAAAAAElFTkSuQmCC");
}
#menu::after {
display: block;
content: '';
padding-top: 80px;
}
#logo {
position: fixed;
bottom: 10px;
right: 10px;
background: rgba(255,255,255,.1);
font-size: 11px;
display: block;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
-webkit-border-radius: 20px;
-moz-border-radius: 20px;
border-radius: 20px;
-webkit-box-shadow: 0 0 3px rgba(0,0,0,.2);
-moz-box-shadow: 0 0 3px rgba(0,0,0,.2);
box-shadow: 0 0 3px rgba(0,0,0,.2);
color: inherit;
}
#menu li a {
display: block;
color: white;
padding: 0 35px 0 25px;
-webkit-transition: background 300ms;
-moz-transition: background 300ms;
}
#menu li {
position: relative;
list-style: none;
}
#menu a:hover,
#menu a.active {
text-decoration: none;
background: rgba(255,255,255,.1);
}
#menu li:hover .cov {
opacity: 1;
}
#menu li .dirname {
opacity: .60;
padding-right: 2px;
}
#menu li .basename {
opacity: 1;
}
#menu .cov {
background: rgba(0,0,0,.4);
position: absolute;
top: 0;
right: 8px;
font-size: 9px;
opacity: .6;
text-align: left;
width: 17px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
padding: 2px 3px;
text-align: center;
}
#stats:nth-child(2n) {
display: inline-block;
margin-top: 15px;
border: 1px solid #eee;
padding: 10px;
-webkit-box-shadow: inset 0 0 2px #eee;
-moz-box-shadow: inset 0 0 2px #eee;
box-shadow: inset 0 0 2px #eee;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
#stats div {
float: left;
padding: 0 5px;
}
#stats::after {
display: block;
content: '';
clear: both;
}
#stats .sloc::after {
content: ' SLOC';
color: #b6b6b6;
}
#stats .percentage::after {
content: ' coverage';
color: #b6b6b6;
}
#stats .hits,
#stats .misses {
display: none;
}
.high {
color: #00d4b4;
}
.medium {
color: #e87d0d;
}
.low {
color: #d4081a;
}
.terrible {
color: #d4081a;
font-weight: bold;
}
table {
width: 80%;
margin-top: 10px;
border-collapse: collapse;
border: 1px solid #cbcbcb;
color: #363636;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
table thead {
display: none;
}
table td.line,
table td.hits {
width: 20px;
background: #eaeaea;
text-align: center;
font-size: 11px;
padding: 0 10px;
color: #949494;
}
table td.hits {
width: 10px;
padding: 2px 5px;
color: rgba(0,0,0,.2);
background: #f0f0f0;
}
tr.miss td.line,
tr.miss td.hits {
background: #e6c3c7;
}
tr.miss td {
background: #f8d5d8;
}
td.source {
padding-left: 15px;
line-height: 15px;
white-space: pre;
font: 12px monaco, monospace;
}
code .comment { color: #ddd }
code .init { color: #2F6FAD }
code .string { color: #5890AD }
code .keyword { color: #8A6343 }
code .number { color: #2F6FAD }
</style></head><body><div id="coverage"><h1 id="overview">Coverage</h1><div id="menu"><li><a href="#overview">overview</a></li><li><span class="cov high">94</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Common/common.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Common/</span><span class="basename">common.js</span></a></li><li><span class="cov high">100</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Common/extend.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Common/</span><span class="basename">extend.js</span></a></li><li><span class="cov medium">62</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Common/function.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Common/</span><span class="basename">function.js</span></a></li><li><span class="cov high">100</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Conf/alias.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Conf/</span><span class="basename">alias.js</span></a></li><li><span class="cov high">100</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Conf/config.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Conf/</span><span class="basename">config.js</span></a></li><li><span class="cov high">100</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Conf/mode.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Conf/</span><span class="basename">mode.js</span></a></li><li><span class="cov high">100</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Conf/tag.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Conf/</span><span class="basename">tag.js</span></a></li><li><span class="cov low">48</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/CheckResourceBehavior.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/</span><span class="basename">CheckResourceBehavior.js</span></a></li><li><span class="cov terrible">11</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/CheckRouteBehavior.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/</span><span class="basename">CheckRouteBehavior.js</span></a></li><li><span class="cov terrible">20</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/DenyIpBehavior.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/</span><span class="basename">DenyIpBehavior.js</span></a></li><li><span class="cov low">47</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/LocationTemplateBehavior.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/</span><span class="basename">LocationTemplateBehavior.js</span></a></li><li><span class="cov high">90</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/ParseTemplateBehavior.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/</span><span class="basename">ParseTemplateBehavior.js</span></a></li><li><span class="cov terrible">10</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/ReadHtmlCacheBehavior.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/</span><span class="basename">ReadHtmlCacheBehavior.js</span></a></li><li><span class="cov low">45</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/WriteHtmlCacheBehavior.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/</span><span class="basename">WriteHtmlCacheBehavior.js</span></a></li><li><span class="cov low">48</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/App.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/</span><span class="basename">App.js</span></a></li><li><span class="cov terrible">11</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Controller.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/</span><span class="basename">Controller.js</span></a></li><li><span class="cov terrible">2</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Db.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/</span><span class="basename">Db.js</span></a></li><li><span class="cov high">87</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Dispatcher.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/</span><span class="basename">Dispatcher.js</span></a></li><li><span class="cov low">40</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Http.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/</span><span class="basename">Http.js</span></a></li><li><span class="cov terrible">5</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Model.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/</span><span class="basename">Model.js</span></a></li><li><span class="cov medium">56</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Think.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/</span><span class="basename">Think.js</span></a></li><li><span class="cov high">76</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/View.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/</span><span class="basename">View.js</span></a></li><li><span class="cov terrible">5</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Cache/FileCache.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Cache/</span><span class="basename">FileCache.js</span></a></li><li><span class="cov low">35</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Cache/MemcacheCache.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Cache/</span><span class="basename">MemcacheCache.js</span></a></li><li><span class="cov terrible">8</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Db/MysqlDb.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Db/</span><span class="basename">MysqlDb.js</span></a></li><li><span class="cov terrible">9</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Session/DbSession.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Session/</span><span class="basename">DbSession.js</span></a></li><li><span class="cov terrible">15</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Session/FileSession.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Session/</span><span class="basename">FileSession.js</span></a></li><li><span class="cov terrible">12</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Socket/MemcacheSocket.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Socket/</span><span class="basename">MemcacheSocket.js</span></a></li><li><span class="cov terrible">8</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Socket/MysqlSocket.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Socket/</span><span class="basename">MysqlSocket.js</span></a></li><li><span class="cov high">100</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Template/EjsTemplate.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Template/</span><span class="basename">EjsTemplate.js</span></a></li><li><span class="cov high">75</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Extend/Controller/RestController.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Extend/Controller/</span><span class="basename">RestController.js</span></a></li><li><span class="cov terrible">5</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Extend/Model/AdvModel.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Extend/Model/</span><span class="basename">AdvModel.js</span></a></li><li><span class="cov high">100</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Behavior.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/</span><span class="basename">Behavior.js</span></a></li><li><span class="cov terrible">11</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Cache.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/</span><span class="basename">Cache.js</span></a></li><li><span class="cov terrible">22</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Cookie.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/</span><span class="basename">Cookie.js</span></a></li><li><span class="cov terrible">3</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Filter.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/</span><span class="basename">Filter.js</span></a></li><li><span class="cov terrible">16</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Session.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/</span><span class="basename">Session.js</span></a></li><li><span class="cov terrible">7</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Valid.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/</span><span class="basename">Valid.js</span></a></li><li><span class="cov terrible">8</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/WebSocket.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/</span><span class="basename">WebSocket.js</span></a></li><li><span class="cov high">100</span><a href="#/Users/welefen/Develop/git/thinkjs/lib/think.js"><span class="dirname">/Users/welefen/Develop/git/thinkjs/lib/</span><span class="basename">think.js</span></a></li><a id="logo" href="http://visionmedia.github.io/mocha/">m</a></div><div id="stats" class="low"><div class="percentage">27%</div><div class="sloc">3110</div><div class="hits">853</div><div class="misses">2257</div></div><div id="files"><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Common/common.js">/Users/welefen/Develop/git/thinkjs/lib/Common/common.js</h2><div id="stats" class="high"><div class="percentage">94%</div><div class="sloc">239</div><div class="hits">227</div><div class="misses">12</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"><td class="line">1</td><td class="hits">1</td><td class="source">var fs = require('fs');</td></tr><tr class="hit"><td class="line">2</td><td class="hits">1</td><td class="source">var path = require('path');</td></tr><tr class="hit"><td class="line">3</td><td class="hits">1</td><td class="source">var util = require('util');</td></tr><tr class="hit"><td class="line">4</td><td class="hits">1</td><td class="source">var crypto = require('crypto');</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">var net = require('net');</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> * 由于非常依赖promise所以将promise设置为全局变量</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> * @type {[type]}</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">11</td><td class="hits">1</td><td class="source">global.Promise = require('es6-promise').Promise;</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> * 动态创建一个类</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> * 提供了继承、扩展、调用父级别方法等方法</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">18</td><td class="hits">1</td><td class="source">global.Class = function (prop, superCls) {</td></tr><tr class="hit"><td class="line">19</td><td class="hits">35</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">20</td><td class="hits">35</td><td class="source"> var cls = function () {</td></tr><tr class="hit"><td class="line">21</td><td class="hits">15</td><td class="source"> function T(args) {</td></tr><tr class="hit"><td class="line">22</td><td class="hits">15</td><td class="source"> for(var name in cls.__prop){</td></tr><tr class="hit"><td class="line">23</td><td class="hits">23</td><td class="source"> var val = cls.__prop[name];</td></tr><tr class="hit"><td class="line">24</td><td class="hits">23</td><td class="source"> this[name] = isObject(val) ? extend({}, val) : val;</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> //自动执行init方法</td></tr><tr class="hit"><td class="line">27</td><td class="hits">15</td><td class="source"> if(isFunction(this.init)){</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> //获取init返回值如果返回一个promise可以让后续执行在then之后</td></tr><tr class="hit"><td class="line">29</td><td class="hits">15</td><td class="source"> this.__initReturn = this.init.apply(this, args);</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">31</td><td class="hits">15</td><td class="source"> return this;</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">33</td><td class="hits">15</td><td class="source"> T.prototype = cls.prototype;</td></tr><tr class="hit"><td class="line">34</td><td class="hits">15</td><td class="source"> T.constructor = cls;</td></tr><tr class="hit"><td class="line">35</td><td class="hits">15</td><td class="source"> return new T(arguments);</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> //类的属性,不放在原型上,实例化的时候调用</td></tr><tr class="hit"><td class="line">38</td><td class="hits">35</td><td class="source"> cls.__prop = {};</td></tr><tr class="hit"><td class="line">39</td><td class="hits">35</td><td class="source"> cls.extend = function(prop){</td></tr><tr class="hit"><td class="line">40</td><td class="hits">36</td><td class="source"> if (isFunction(prop)) {</td></tr><tr class="hit"><td class="line">41</td><td class="hits">34</td><td class="source"> prop = prop();</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">43</td><td class="hits">36</td><td class="source"> if (isObject(prop)) {</td></tr><tr class="hit"><td class="line">44</td><td class="hits">34</td><td class="source"> for(var name in prop){</td></tr><tr class="hit"><td class="line">45</td><td class="hits">353</td><td class="source"> var val = prop[name];</td></tr><tr class="hit"><td class="line">46</td><td class="hits">353</td><td class="source"> if (isFunction(val)) {</td></tr><tr class="hit"><td class="line">47</td><td class="hits">308</td><td class="source"> this.prototype[name] = val;</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="hit"><td class="line">49</td><td class="hits">45</td><td class="source"> cls.__prop[name] = isObject(val) ? extend({}, val) : val;</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">53</td><td class="hits">36</td><td class="source"> return this;</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> };</td></tr><tr class="hit"><td class="line">55</td><td class="hits">35</td><td class="source"> cls.inherits = function(superCls){</td></tr><tr class="hit"><td class="line">56</td><td class="hits">22</td><td class="source"> util.inherits(this, superCls);</td></tr><tr><td class="line">57</td><td class="hits"></td><td class="source"> //将父级的属性复制到当前类上</td></tr><tr class="hit"><td class="line">58</td><td class="hits">22</td><td class="source"> extend(cls.__prop, superCls.__prop);</td></tr><tr class="hit"><td class="line">59</td><td class="hits">22</td><td class="source"> return this;</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> };</td></tr><tr class="hit"><td class="line">61</td><td class="hits">35</td><td class="source"> if (superCls === true &amp;&amp; isFunction(prop)) {</td></tr><tr class="hit"><td class="line">62</td><td class="hits">1</td><td class="source"> superCls = prop;</td></tr><tr class="hit"><td class="line">63</td><td class="hits">1</td><td class="source"> prop = undefined;</td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">65</td><td class="hits">35</td><td class="source"> if (isFunction(superCls)) {</td></tr><tr class="hit"><td class="line">66</td><td class="hits">22</td><td class="source"> cls.inherits(superCls);</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">68</td><td class="hits"></td><td class="source"> //调用父级方法</td></tr><tr class="hit"><td class="line">69</td><td class="hits">35</td><td class="source"> cls.prototype.super = cls.prototype.super_ = function(name, data){</td></tr><tr><td class="line">70</td><td class="hits"></td><td class="source"> //如果当前类没有这个方法,则直接返回。</td></tr><tr><td class="line">71</td><td class="hits"></td><td class="source"> //用于在a方法调用父级的b方法</td></tr><tr class="hit"><td class="line">72</td><td class="hits">6</td><td class="source"> if (!this[name]) {</td></tr><tr class="hit"><td class="line">73</td><td class="hits">1</td><td class="source"> return;</td></tr><tr><td class="line">74</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">75</td><td class="hits">5</td><td class="source"> var super_ = this.constructor.super_;</td></tr><tr><td class="line">76</td><td class="hits"></td><td class="source"> //如果父级没有这个方法,那么直接返回</td></tr><tr class="hit"><td class="line">77</td><td class="hits">5</td><td class="source"> if (!isFunction(super_.prototype[name])) {</td></tr><tr class="hit"><td class="line">78</td><td class="hits">1</td><td class="source"> return;</td></tr><tr><td class="line">79</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">80</td><td class="hits"></td><td class="source"> //如果参数不是数组,自动转为数组</td></tr><tr class="hit"><td class="line">81</td><td class="hits">4</td><td class="source"> if (!isArray(data)) {</td></tr><tr class="hit"><td class="line">82</td><td class="hits">4</td><td class="source"> data = [data];</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">84</td><td class="hits">4</td><td class="source"> while(1){</td></tr><tr class="hit"><td class="line">85</td><td class="hits">5</td><td class="source"> if (this[name] === super_.prototype[name] &amp;&amp; super_.super_) {</td></tr><tr class="hit"><td class="line">86</td><td class="hits">1</td><td class="source"> super_ = super_.super_;</td></tr><tr><td class="line">87</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="hit"><td class="line">88</td><td class="hits">4</td><td class="source"> break;</td></tr><tr><td class="line">89</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">91</td><td class="hits">4</td><td class="source"> var method = super_.prototype[name];</td></tr><tr class="hit"><td class="line">92</td><td class="hits">4</td><td class="source"> delete super_.prototype[name];</td></tr><tr class="hit"><td class="line">93</td><td class="hits">4</td><td class="source"> var ret = method.apply(this, data);</td></tr><tr class="hit"><td class="line">94</td><td class="hits">4</td><td class="source"> super_.prototype[name] = method;</td></tr><tr class="hit"><td class="line">95</td><td class="hits">4</td><td class="source"> return ret;</td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source"> };</td></tr><tr class="hit"><td class="line">97</td><td class="hits">35</td><td class="source"> if (prop) {</td></tr><tr class="hit"><td class="line">98</td><td class="hits">34</td><td class="source"> cls.extend(prop);</td></tr><tr><td class="line">99</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">100</td><td class="hits">35</td><td class="source"> return cls;</td></tr><tr><td class="line">101</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">102</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">103</td><td class="hits"></td><td class="source"> * extend, from jquery具有深度复制功能</td></tr><tr><td class="line">104</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">105</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">106</td><td class="hits">1</td><td class="source">global.extend = function(){</td></tr><tr class="hit"><td class="line">107</td><td class="hits">104</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">108</td><td class="hits">104</td><td class="source"> var args = [].slice.call(arguments);</td></tr><tr class="hit"><td class="line">109</td><td class="hits">104</td><td class="source"> var deep = true;</td></tr><tr class="hit"><td class="line">110</td><td class="hits">104</td><td class="source"> var target = args.shift();</td></tr><tr class="hit"><td class="line">111</td><td class="hits">104</td><td class="source"> if (isBoolean(target)) {</td></tr><tr class="hit"><td class="line">112</td><td class="hits">40</td><td class="source"> deep = target;</td></tr><tr class="hit"><td class="line">113</td><td class="hits">40</td><td class="source"> target = args.shift();</td></tr><tr><td class="line">114</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">115</td><td class="hits">104</td><td class="source"> target = target || {};</td></tr><tr class="hit"><td class="line">116</td><td class="hits">104</td><td class="source"> var length = args.length;</td></tr><tr class="hit"><td class="line">117</td><td class="hits">104</td><td class="source"> var options, name, src, copy, copyAsArray, clone;</td></tr><tr class="hit"><td class="line">118</td><td class="hits">104</td><td class="source"> for(var i = 0; i &lt; length; i++){</td></tr><tr class="hit"><td class="line">119</td><td class="hits">104</td><td class="source"> options = args[i] || {};</td></tr><tr class="hit"><td class="line">120</td><td class="hits">104</td><td class="source"> if (isFunction(options)) {</td></tr><tr class="hit"><td class="line">121</td><td class="hits">1</td><td class="source"> options = options();</td></tr><tr><td class="line">122</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">123</td><td class="hits">104</td><td class="source"> for(name in options){</td></tr><tr class="hit"><td class="line">124</td><td class="hits">240</td><td class="source"> src = target[name];</td></tr><tr class="hit"><td class="line">125</td><td class="hits">240</td><td class="source"> copy = options[name];</td></tr><tr class="hit"><td class="line">126</td><td class="hits">240</td><td class="source"> if (src === copy) {</td></tr><tr class="hit"><td class="line">127</td><td class="hits">26</td><td class="source"> continue;</td></tr><tr><td class="line">128</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">129</td><td class="hits">214</td><td class="source"> if (deep &amp;&amp; copy &amp;&amp; (isObject(copy) || (copyAsArray = isArray(copy) ))) {</td></tr><tr class="hit"><td class="line">130</td><td class="hits">38</td><td class="source"> if (copyAsArray) {</td></tr><tr class="hit"><td class="line">131</td><td class="hits">12</td><td class="source"> copyAsArray = false;</td></tr><tr class="hit"><td class="line">132</td><td class="hits">12</td><td class="source"> clone = src &amp;&amp; isArray(src) ? src : [];</td></tr><tr><td class="line">133</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="hit"><td class="line">134</td><td class="hits">26</td><td class="source"> clone = src &amp;&amp; isObject(src) ? src : {}; </td></tr><tr><td class="line">135</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">136</td><td class="hits">38</td><td class="source"> target[name] = extend(deep, clone, copy);</td></tr><tr class="hit"><td class="line">137</td><td class="hits">176</td><td class="source"> }else if (copy !== undefined) {</td></tr><tr class="hit"><td class="line">138</td><td class="hits">176</td><td class="source"> target[name] = copy;</td></tr><tr><td class="line">139</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">140</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">141</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">142</td><td class="hits">104</td><td class="source"> return target;</td></tr><tr><td class="line">143</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">144</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">145</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">146</td><td class="hits"></td><td class="source">//Object上toString方法</td></tr><tr class="hit"><td class="line">147</td><td class="hits">1</td><td class="source">var toString = Object.prototype.toString;</td></tr><tr><td class="line">148</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">149</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">150</td><td class="hits"></td><td class="source"> * 是否是boolean</td></tr><tr><td class="line">151</td><td class="hits"></td><td class="source"> * @param {[type]} obj</td></tr><tr><td class="line">152</td><td class="hits"></td><td class="source"> * @return {Boolean}</td></tr><tr><td class="line">153</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">154</td><td class="hits">1</td><td class="source">global.isBoolean = function(obj){</td></tr><tr class="hit"><td class="line">155</td><td class="hits">115</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">156</td><td class="hits">115</td><td class="source"> return toString.call(obj) === '[object Boolean]';</td></tr><tr><td class="line">157</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">158</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">159</td><td class="hits"></td><td class="source"> * 是否是数字</td></tr><tr><td class="line">160</td><td class="hits"></td><td class="source"> * @param {[type]} obj [description]</td></tr><tr><td class="line">161</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">162</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">163</td><td class="hits">1</td><td class="source">global.isNumber = function(obj){</td></tr><tr class="hit"><td class="line">164</td><td class="hits">18</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">165</td><td class="hits">18</td><td class="source"> return toString.call(obj) === '[object Number]';</td></tr><tr><td class="line">166</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">167</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">168</td><td class="hits"></td><td class="source"> * 是否是个对象</td></tr><tr><td class="line">169</td><td class="hits"></td><td class="source"> * @param {[type]} obj [description]</td></tr><tr><td class="line">170</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">171</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">172</td><td class="hits">1</td><td class="source">global.isObject = function(obj){</td></tr><tr class="hit"><td class="line">173</td><td class="hits">288</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">174</td><td class="hits">288</td><td class="source"> return toString.call(obj) === '[object Object]';</td></tr><tr><td class="line">175</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">176</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">177</td><td class="hits"></td><td class="source"> * 是否是字符串</td></tr><tr><td class="line">178</td><td class="hits"></td><td class="source"> * @param {[type]} obj [description]</td></tr><tr><td class="line">179</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">180</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">181</td><td class="hits">1</td><td class="source">global.isString = function(obj){</td></tr><tr class="hit"><td class="line">182</td><td class="hits">201</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">183</td><td class="hits">201</td><td class="source"> return toString.call(obj) === '[object String]';</td></tr><tr><td class="line">184</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">185</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">186</td><td class="hits"></td><td class="source"> * 是否是个function</td></tr><tr><td class="line">187</td><td class="hits"></td><td class="source"> * @param {[type]} obj [description]</td></tr><tr><td class="line">188</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">189</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">190</td><td class="hits">1</td><td class="source">global.isFunction = function(obj){</td></tr><tr class="hit"><td class="line">191</td><td class="hits">670</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">192</td><td class="hits">670</td><td class="source"> return typeof obj === 'function';</td></tr><tr><td class="line">193</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">194</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">195</td><td class="hits"></td><td class="source"> * 是否是日期</td></tr><tr><td class="line">196</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">197</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">198</td><td class="hits">1</td><td class="source">global.isDate = function(obj){</td></tr><tr class="hit"><td class="line">199</td><td class="hits">2</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">200</td><td class="hits">2</td><td class="source"> return util.isDate(obj);</td></tr><tr><td class="line">201</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">202</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">203</td><td class="hits"></td><td class="source"> * 是否是正则</td></tr><tr><td class="line">204</td><td class="hits"></td><td class="source"> * @param {[type]} reg [description]</td></tr><tr><td class="line">205</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">206</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">207</td><td class="hits">1</td><td class="source">global.isRegexp = function(obj){</td></tr><tr class="hit"><td class="line">208</td><td class="hits">2</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">209</td><td class="hits">2</td><td class="source"> return util.isRegExp(obj);</td></tr><tr><td class="line">210</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">211</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">212</td><td class="hits"></td><td class="source"> * 是否是个错误</td></tr><tr><td class="line">213</td><td class="hits"></td><td class="source"> * @param {[type]} obj [description]</td></tr><tr><td class="line">214</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">215</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">216</td><td class="hits">1</td><td class="source">global.isError = function(obj){</td></tr><tr class="hit"><td class="line">217</td><td class="hits">2</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">218</td><td class="hits">2</td><td class="source"> return util.isError(obj);</td></tr><tr><td class="line">219</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">220</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">221</td><td class="hits"></td><td class="source"> * 判断对象是否为空</td></tr><tr><td class="line">222</td><td class="hits"></td><td class="source"> * @param {[type]} obj</td></tr><tr><td class="line">223</td><td class="hits"></td><td class="source"> * @return {Boolean}</td></tr><tr><td class="line">224</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">225</td><td class="hits">1</td><td class="source">global.isEmpty = function(obj){</td></tr><tr class="hit"><td class="line">226</td><td class="hits">12</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">227</td><td class="hits">12</td><td class="source"> if (isObject(obj)) {</td></tr><tr class="hit"><td class="line">228</td><td class="hits">2</td><td class="source"> var key;</td></tr><tr class="hit"><td class="line">229</td><td class="hits">2</td><td class="source"> for(key in obj){</td></tr><tr class="hit"><td class="line">230</td><td class="hits">1</td><td class="source"> return false;</td></tr><tr><td class="line">231</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">232</td><td class="hits">1</td><td class="source"> return true;</td></tr><tr class="hit"><td class="line">233</td><td class="hits">10</td><td class="source"> }else if (isArray(obj)) {</td></tr><tr class="hit"><td class="line">234</td><td class="hits">1</td><td class="source"> return obj.length === 0;</td></tr><tr class="hit"><td class="line">235</td><td class="hits">9</td><td class="source"> }else if (isString(obj)) {</td></tr><tr class="hit"><td class="line">236</td><td class="hits">2</td><td class="source"> return obj.length === 0;</td></tr><tr class="hit"><td class="line">237</td><td class="hits">7</td><td class="source"> }else if (isNumber(obj)) {</td></tr><tr class="hit"><td class="line">238</td><td class="hits">2</td><td class="source"> return obj === 0;</td></tr><tr class="hit"><td class="line">239</td><td class="hits">5</td><td class="source"> }else if (obj === null || obj === undefined) {</td></tr><tr class="hit"><td class="line">240</td><td class="hits">2</td><td class="source"> return true;</td></tr><tr class="hit"><td class="line">241</td><td class="hits">3</td><td class="source"> }else if (isBoolean(obj)) {</td></tr><tr class="hit"><td class="line">242</td><td class="hits">2</td><td class="source"> return !obj;</td></tr><tr><td class="line">243</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">244</td><td class="hits">1</td><td class="source"> return false;</td></tr><tr><td class="line">245</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">246</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">247</td><td class="hits"></td><td class="source"> * 是否是个标量</td></tr><tr><td class="line">248</td><td class="hits"></td><td class="source"> * @param {[type]} obj [description]</td></tr><tr><td class="line">249</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">250</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">251</td><td class="hits">1</td><td class="source">global.isScalar = function(obj){</td></tr><tr class="hit"><td class="line">252</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">253</td><td class="hits">1</td><td class="source"> return isBoolean(obj) || isNumber(obj) || isString(obj);</td></tr><tr><td class="line">254</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">255</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">256</td><td class="hits"></td><td class="source"> * 是否是个数组</td></tr><tr><td class="line">257</td><td class="hits"></td><td class="source"> * @type {Boolean}</td></tr><tr><td class="line">258</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">259</td><td class="hits">1</td><td class="source">global.isArray = Array.isArray;</td></tr><tr><td class="line">260</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">261</td><td class="hits"></td><td class="source"> * 是否是IP</td></tr><tr><td class="line">262</td><td class="hits"></td><td class="source"> * @type {Boolean}</td></tr><tr><td class="line">263</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">264</td><td class="hits">1</td><td class="source">global.isIP = net.isIP;</td></tr><tr class="hit"><td class="line">265</td><td class="hits">1</td><td class="source">global.isIP4 = net.isIP4;</td></tr><tr class="hit"><td class="line">266</td><td class="hits">1</td><td class="source">global.isIP6 = net.isIP6;</td></tr><tr><td class="line">267</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">268</td><td class="hits"></td><td class="source"> * 是否是个文件</td></tr><tr><td class="line">269</td><td class="hits"></td><td class="source"> * @param {[type]} p [description]</td></tr><tr><td class="line">270</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">271</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">272</td><td class="hits">1</td><td class="source">global.isFile = function(p){</td></tr><tr class="hit"><td class="line">273</td><td class="hits">49</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">274</td><td class="hits">49</td><td class="source"> if (!fs.existsSync(p)) {</td></tr><tr class="hit"><td class="line">275</td><td class="hits">24</td><td class="source"> return false;</td></tr><tr><td class="line">276</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">277</td><td class="hits">25</td><td class="source"> var stats = fs.statSync(p);</td></tr><tr class="hit"><td class="line">278</td><td class="hits">25</td><td class="source"> return stats.isFile();</td></tr><tr><td class="line">279</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">280</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">281</td><td class="hits"></td><td class="source"> * 是否是个目录</td></tr><tr><td class="line">282</td><td class="hits"></td><td class="source"> * @param {[type]} p [description]</td></tr><tr><td class="line">283</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">284</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">285</td><td class="hits">1</td><td class="source">global.isDir = function(p){</td></tr><tr class="hit"><td class="line">286</td><td class="hits">3</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">287</td><td class="hits">3</td><td class="source"> if (!fs.existsSync(p)) {</td></tr><tr class="hit"><td class="line">288</td><td class="hits">1</td><td class="source"> return false;</td></tr><tr><td class="line">289</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">290</td><td class="hits">2</td><td class="source"> var stats = fs.statSync(p);</td></tr><tr class="hit"><td class="line">291</td><td class="hits">2</td><td class="source"> return stats.isDirectory();</td></tr><tr><td class="line">292</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">293</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">294</td><td class="hits"></td><td class="source"> * 是否是buffer</td></tr><tr><td class="line">295</td><td class="hits"></td><td class="source"> * @type {Boolean}</td></tr><tr><td class="line">296</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">297</td><td class="hits">1</td><td class="source">global.isBuffer = Buffer.isBuffer;</td></tr><tr><td class="line">298</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">299</td><td class="hits"></td><td class="source"> * 是否是个数字的字符串</td></tr><tr><td class="line">300</td><td class="hits"></td><td class="source"> * @param {[type]} obj [description]</td></tr><tr><td class="line">301</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">302</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">303</td><td class="hits">1</td><td class="source">var numberReg = /^((\d*\.?\d*(?:e[+-]?\d*(?:\d?\.?|\.?\d?)\d*)?)|(0[0-7]+)|(0x[0-9a-f]+))$/i;</td></tr><tr class="hit"><td class="line">304</td><td class="hits">1</td><td class="source">global.isNumberString = function(obj){</td></tr><tr class="hit"><td class="line">305</td><td class="hits">3</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">306</td><td class="hits">3</td><td class="source"> return numberReg.test(obj);</td></tr><tr><td class="line">307</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">308</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">309</td><td class="hits"></td><td class="source"> * 判断是否是个promise</td></tr><tr><td class="line">310</td><td class="hits"></td><td class="source"> * @param {[type]} obj [description]</td></tr><tr><td class="line">311</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">312</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">313</td><td class="hits">1</td><td class="source">global.isPromise = function(obj){</td></tr><tr class="hit"><td class="line">314</td><td class="hits">33</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">315</td><td class="hits">33</td><td class="source"> return !!(obj &amp;&amp; typeof obj.then === 'function');</td></tr><tr><td class="line">316</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">317</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">318</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">319</td><td class="hits"></td><td class="source"> * 判断一个文件或者目录是否可写</td></tr><tr><td class="line">320</td><td class="hits"></td><td class="source"> * @param {[type]} p [description]</td></tr><tr><td class="line">321</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">322</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">323</td><td class="hits">1</td><td class="source">global.isWritable = function(p){</td></tr><tr class="hit"><td class="line">324</td><td class="hits">3</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">325</td><td class="hits">3</td><td class="source"> if (!fs.existsSync(p)) {</td></tr><tr class="hit"><td class="line">326</td><td class="hits">1</td><td class="source"> return false;</td></tr><tr><td class="line">327</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">328</td><td class="hits">2</td><td class="source"> var stats = fs.statSync(p);</td></tr><tr class="hit"><td class="line">329</td><td class="hits">2</td><td class="source"> var mode = stats.mode;</td></tr><tr class="hit"><td class="line">330</td><td class="hits">2</td><td class="source"> var uid = process.getuid ? process.getuid() : 0;</td></tr><tr class="hit"><td class="line">331</td><td class="hits">2</td><td class="source"> var gid = process.getgid ? process.getgid() : 0;</td></tr><tr class="hit"><td class="line">332</td><td class="hits">2</td><td class="source"> var owner = uid === stats.uid;</td></tr><tr class="hit"><td class="line">333</td><td class="hits">2</td><td class="source"> var group = gid === stats.gid;</td></tr><tr class="hit"><td class="line">334</td><td class="hits">2</td><td class="source"> return !!(owner &amp;&amp; (mode &amp; parseInt('00200', 8)) || </td></tr><tr><td class="line">335</td><td class="hits"></td><td class="source"> group &amp;&amp; (mode &amp; parseInt('00020', 8)) || </td></tr><tr><td class="line">336</td><td class="hits"></td><td class="source"> (mode &amp; parseInt('00002', 8)));</td></tr><tr><td class="line">337</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">338</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">339</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">340</td><td class="hits"></td><td class="source"> * 递归创建目录,同步模式</td></tr><tr><td class="line">341</td><td class="hits"></td><td class="source"> * @param {[type]} p [description]</td></tr><tr><td class="line">342</td><td class="hits"></td><td class="source"> * @param {[type]} mode [description]</td></tr><tr><td class="line">343</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">344</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">345</td><td class="hits">1</td><td class="source">global.mkdir = function(p, mode){</td></tr><tr class="hit"><td class="line">346</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">347</td><td class="hits">1</td><td class="source"> mode = mode || '0777';</td></tr><tr class="hit"><td class="line">348</td><td class="hits">1</td><td class="source"> if (fs.existsSync(p)) {</td></tr><tr class="miss"><td class="line">349</td><td class="hits">0</td><td class="source"> chmod(p, mode);</td></tr><tr class="miss"><td class="line">350</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">351</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">352</td><td class="hits">1</td><td class="source"> var pp = path.dirname(p);</td></tr><tr class="hit"><td class="line">353</td><td class="hits">1</td><td class="source"> if (fs.existsSync(pp)) {</td></tr><tr class="hit"><td class="line">354</td><td class="hits">1</td><td class="source"> fs.mkdirSync(p, mode);</td></tr><tr><td class="line">355</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">356</td><td class="hits">0</td><td class="source"> mkdir(pp, mode);</td></tr><tr class="miss"><td class="line">357</td><td class="hits">0</td><td class="source"> mkdir(p, mode);</td></tr><tr><td class="line">358</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">359</td><td class="hits">1</td><td class="source"> return true;</td></tr><tr><td class="line">360</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">361</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">362</td><td class="hits"></td><td class="source"> * 修改目录或者文件权限</td></tr><tr><td class="line">363</td><td class="hits"></td><td class="source"> * @param {[type]} p [description]</td></tr><tr><td class="line">364</td><td class="hits"></td><td class="source"> * @param {[type]} mode [description]</td></tr><tr><td class="line">365</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">366</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">367</td><td class="hits">1</td><td class="source">global.chmod = function(p, mode){</td></tr><tr class="miss"><td class="line">368</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">369</td><td class="hits">0</td><td class="source"> mode = mode || '0777';</td></tr><tr class="miss"><td class="line">370</td><td class="hits">0</td><td class="source"> if (!fs.existsSync(p)) {</td></tr><tr class="miss"><td class="line">371</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">372</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">373</td><td class="hits">0</td><td class="source"> return fs.chmodSync(p, mode);</td></tr><tr><td class="line">374</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">375</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">376</td><td class="hits"></td><td class="source"> * 获取文件内容</td></tr><tr><td class="line">377</td><td class="hits"></td><td class="source"> * @param {[type]} file [description]</td></tr><tr><td class="line">378</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">379</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">380</td><td class="hits">1</td><td class="source">global.getFileContent = function(file, encoding){</td></tr><tr class="hit"><td class="line">381</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">382</td><td class="hits">1</td><td class="source"> if (!fs.existsSync(file)) {</td></tr><tr class="miss"><td class="line">383</td><td class="hits">0</td><td class="source"> return '';</td></tr><tr><td class="line">384</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">385</td><td class="hits">1</td><td class="source"> return fs.readFileSync(file, {</td></tr><tr><td class="line">386</td><td class="hits"></td><td class="source"> encoding: encoding || 'utf8'</td></tr><tr><td class="line">387</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">388</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">389</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">390</td><td class="hits"></td><td class="source"> * 设置文件内容</td></tr><tr><td class="line">391</td><td class="hits"></td><td class="source"> * @param {[type]} file [description]</td></tr><tr><td class="line">392</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">393</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">394</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">395</td><td class="hits">1</td><td class="source">global.setFileContent = function(file, data){</td></tr><tr class="miss"><td class="line">396</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">397</td><td class="hits">0</td><td class="source"> return fs.writeFileSync(file, data);</td></tr><tr><td class="line">398</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">399</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">400</td><td class="hits"></td><td class="source"> * 大写首字符</td></tr><tr><td class="line">401</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">402</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">403</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">404</td><td class="hits">1</td><td class="source">global.ucfirst = function(name){</td></tr><tr class="hit"><td class="line">405</td><td class="hits">11</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">406</td><td class="hits">11</td><td class="source"> name = (name || '') + '';</td></tr><tr class="hit"><td class="line">407</td><td class="hits">11</td><td class="source"> return name.substr(0,1).toUpperCase() + name.substr(1).toLowerCase();</td></tr><tr><td class="line">408</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">409</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">410</td><td class="hits"></td><td class="source"> * 获取字符串的md5</td></tr><tr><td class="line">411</td><td class="hits"></td><td class="source"> * @param {[type]} str [description]</td></tr><tr><td class="line">412</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">413</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">414</td><td class="hits">1</td><td class="source">global.md5 = function(str){</td></tr><tr class="hit"><td class="line">415</td><td class="hits">2</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">416</td><td class="hits">2</td><td class="source"> var instance = crypto.createHash('md5');</td></tr><tr class="hit"><td class="line">417</td><td class="hits">2</td><td class="source"> instance.update(str + '');</td></tr><tr class="hit"><td class="line">418</td><td class="hits">2</td><td class="source"> return instance.digest('hex');</td></tr><tr><td class="line">419</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">420</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">421</td><td class="hits"></td><td class="source"> * 生成一个promise,如果传入的参数是promise则直接返回</td></tr><tr><td class="line">422</td><td class="hits"></td><td class="source"> * @param {[type]} obj [description]</td></tr><tr><td class="line">423</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">424</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">425</td><td class="hits">1</td><td class="source">global.getPromise = function(obj, reject){</td></tr><tr class="hit"><td class="line">426</td><td class="hits">28</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">427</td><td class="hits">28</td><td class="source"> if (isPromise(obj)) {</td></tr><tr class="hit"><td class="line">428</td><td class="hits">7</td><td class="source"> return obj;</td></tr><tr><td class="line">429</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">430</td><td class="hits">21</td><td class="source"> if (reject) {</td></tr><tr class="hit"><td class="line">431</td><td class="hits">2</td><td class="source"> return Promise.reject(obj);</td></tr><tr><td class="line">432</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">433</td><td class="hits">19</td><td class="source"> return Promise.resolve(obj);</td></tr><tr><td class="line">434</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">435</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">436</td><td class="hits"></td><td class="source"> * 生成一个defer对象</td></tr><tr><td class="line">437</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">438</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">439</td><td class="hits">1</td><td class="source">global.getDefer = function(){</td></tr><tr class="hit"><td class="line">440</td><td class="hits">2</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">441</td><td class="hits">2</td><td class="source"> var deferred = {};</td></tr><tr class="hit"><td class="line">442</td><td class="hits">2</td><td class="source"> deferred.promise = new Promise(function(resolve, reject){</td></tr><tr class="hit"><td class="line">443</td><td class="hits">2</td><td class="source"> deferred.resolve = resolve;</td></tr><tr class="hit"><td class="line">444</td><td class="hits">2</td><td class="source"> deferred.reject = reject;</td></tr><tr><td class="line">445</td><td class="hits"></td><td class="source"> });</td></tr><tr class="hit"><td class="line">446</td><td class="hits">2</td><td class="source"> return deferred;</td></tr><tr><td class="line">447</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">448</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">449</td><td class="hits"></td><td class="source"> * 快速生成一个object</td></tr><tr><td class="line">450</td><td class="hits"></td><td class="source"> * @param {[type]} key [description]</td></tr><tr><td class="line">451</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">452</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">453</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">454</td><td class="hits">1</td><td class="source">global.getObject = function(key, value){</td></tr><tr class="hit"><td class="line">455</td><td class="hits">5</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">456</td><td class="hits">5</td><td class="source"> var obj = {};</td></tr><tr class="hit"><td class="line">457</td><td class="hits">5</td><td class="source"> if (!isArray(key)) {</td></tr><tr class="hit"><td class="line">458</td><td class="hits">2</td><td class="source"> obj[key] = value;</td></tr><tr class="hit"><td class="line">459</td><td class="hits">2</td><td class="source"> return obj;</td></tr><tr><td class="line">460</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">461</td><td class="hits">3</td><td class="source"> key.forEach(function(item, i){</td></tr><tr class="hit"><td class="line">462</td><td class="hits">5</td><td class="source"> obj[item] = value[i];</td></tr><tr><td class="line">463</td><td class="hits"></td><td class="source"> });</td></tr><tr class="hit"><td class="line">464</td><td class="hits">3</td><td class="source"> return obj;</td></tr><tr><td class="line">465</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">466</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">467</td><td class="hits"></td><td class="source"> * 将数组变成对象</td></tr><tr><td class="line">468</td><td class="hits"></td><td class="source"> * @param {[type]} arr [description]</td></tr><tr><td class="line">469</td><td class="hits"></td><td class="source"> * @param {[type]} key [description]</td></tr><tr><td class="line">470</td><td class="hits"></td><td class="source"> * @param {[type]} valueKeys [description]</td></tr><tr><td class="line">471</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">472</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">473</td><td class="hits">1</td><td class="source">global.arrToObj = function(arr, key, valueKey){</td></tr><tr class="hit"><td class="line">474</td><td class="hits">4</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">475</td><td class="hits">4</td><td class="source"> var result = {};</td></tr><tr class="hit"><td class="line">476</td><td class="hits">4</td><td class="source"> var arrResult = [];</td></tr><tr class="hit"><td class="line">477</td><td class="hits">4</td><td class="source"> arr.forEach(function(item){</td></tr><tr class="hit"><td class="line">478</td><td class="hits">8</td><td class="source"> var keyValue = item[key];</td></tr><tr class="hit"><td class="line">479</td><td class="hits">8</td><td class="source"> if (valueKey === null) {</td></tr><tr class="hit"><td class="line">480</td><td class="hits">4</td><td class="source"> arrResult.push(keyValue);</td></tr><tr class="hit"><td class="line">481</td><td class="hits">4</td><td class="source"> }else if (valueKey) {</td></tr><tr class="hit"><td class="line">482</td><td class="hits">2</td><td class="source"> result[keyValue] = item[valueKey];</td></tr><tr><td class="line">483</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="hit"><td class="line">484</td><td class="hits">2</td><td class="source"> result[keyValue] = item;</td></tr><tr><td class="line">485</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">486</td><td class="hits"></td><td class="source"> })</td></tr><tr class="hit"><td class="line">487</td><td class="hits">4</td><td class="source"> return valueKey === null ? arrResult : result;</td></tr><tr><td class="line">488</td><td class="hits"></td><td class="source">}</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Common/extend.js">/Users/welefen/Develop/git/thinkjs/lib/Common/extend.js</h2><div id="stats" class="high"><div class="percentage">100%</div><div class="sloc">13</div><div class="hits">13</div><div class="misses">0</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">//该文件内容为原生对象的扩展</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> * 获取对象的值</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> * @param {[type]} obj [description]</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">8</td><td class="hits">1</td><td class="source">Object.values = function(obj){</td></tr><tr class="hit"><td class="line">9</td><td class="hits">4</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">10</td><td class="hits">4</td><td class="source"> var values = [];</td></tr><tr class="hit"><td class="line">11</td><td class="hits">4</td><td class="source"> for(var key in obj){</td></tr><tr class="hit"><td class="line">12</td><td class="hits">1</td><td class="source"> if (obj.hasOwnProperty(key)) {</td></tr><tr class="hit"><td class="line">13</td><td class="hits">1</td><td class="source"> values.push(obj[key])</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">16</td><td class="hits">4</td><td class="source"> return values;</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> * 数组求和</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">22</td><td class="hits">1</td><td class="source">Array.prototype.sum = function(){</td></tr><tr class="hit"><td class="line">23</td><td class="hits">7</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">24</td><td class="hits">7</td><td class="source"> var count = 0;</td></tr><tr class="hit"><td class="line">25</td><td class="hits">7</td><td class="source"> this.forEach(function(item){</td></tr><tr class="hit"><td class="line">26</td><td class="hits">23</td><td class="source"> count += parseFloat(item) || 0;</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> });</td></tr><tr class="hit"><td class="line">28</td><td class="hits">7</td><td class="source"> return count;</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> </td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Common/function.js">/Users/welefen/Develop/git/thinkjs/lib/Common/function.js</h2><div id="stats" class="medium"><div class="percentage">62%</div><div class="sloc">161</div><div class="hits">100</div><div class="misses">61</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"><td class="line">1</td><td class="hits">1</td><td class="source">var fs = require('fs');</td></tr><tr class="hit"><td class="line">2</td><td class="hits">1</td><td class="source">var path = require('path');</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">var _alias = {};</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">var _autoload_callbacks = [];</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> * thinkRequire获取到的路径</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">12</td><td class="hits">1</td><td class="source">function getThinkRequirePath(name){</td></tr><tr class="hit"><td class="line">13</td><td class="hits">72</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">14</td><td class="hits">72</td><td class="source"> if (_alias[name]) {</td></tr><tr class="hit"><td class="line">15</td><td class="hits">53</td><td class="source"> return _alias[name];</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">17</td><td class="hits">19</td><td class="source"> var result = '';</td></tr><tr class="hit"><td class="line">18</td><td class="hits">19</td><td class="source"> _autoload_callbacks.some(function(callback){</td></tr><tr class="hit"><td class="line">19</td><td class="hits">19</td><td class="source"> result = callback &amp;&amp; callback(name);</td></tr><tr class="hit"><td class="line">20</td><td class="hits">19</td><td class="source"> if (result) {</td></tr><tr class="hit"><td class="line">21</td><td class="hits">18</td><td class="source"> return true;</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> });</td></tr><tr class="hit"><td class="line">24</td><td class="hits">19</td><td class="source"> return result;</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source">}</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> * 自定义的require, 加入别名功能</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> * @type {[type]}</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">30</td><td class="hits">1</td><td class="source">global.thinkRequire = function(name){</td></tr><tr class="hit"><td class="line">31</td><td class="hits">72</td><td class="source"> 'use strict';</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> //如果不是字符串则直接返回</td></tr><tr class="hit"><td class="line">33</td><td class="hits">72</td><td class="source"> if (!isString(name)) {</td></tr><tr class="hit"><td class="line">34</td><td class="hits">1</td><td class="source"> return name;</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">36</td><td class="hits">71</td><td class="source"> var path = name;</td></tr><tr class="hit"><td class="line">37</td><td class="hits">71</td><td class="source"> if (path[0] !== '/') {</td></tr><tr class="hit"><td class="line">38</td><td class="hits">71</td><td class="source"> path = getThinkRequirePath(name);</td></tr><tr><td class="line">39</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">40</td><td class="hits">71</td><td class="source"> if (path) {</td></tr><tr class="hit"><td class="line">41</td><td class="hits">70</td><td class="source"> var obj = require(path);</td></tr><tr class="hit"><td class="line">42</td><td class="hits">70</td><td class="source"> if (isFunction(obj)) {</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> //修正子类继承的方法获取到正确的文件名</td></tr><tr class="hit"><td class="line">44</td><td class="hits">64</td><td class="source"> obj.prototype.__filename = path;</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">46</td><td class="hits">70</td><td class="source"> return obj;</td></tr><tr><td class="line">47</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">48</td><td class="hits">1</td><td class="source"> return require(name);</td></tr><tr><td class="line">49</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> * 注册require</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> * @param {Function} callback [description]</td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">55</td><td class="hits">1</td><td class="source">global.registerAutoload = function(callback){</td></tr><tr class="hit"><td class="line">56</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">57</td><td class="hits">1</td><td class="source"> _autoload_callbacks.push(callback);</td></tr><tr><td class="line">58</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">59</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> * 别名</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">62</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">63</td><td class="hits">1</td><td class="source">global.aliasImport = function(alias, classFile){</td></tr><tr class="hit"><td class="line">64</td><td class="hits">19</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">65</td><td class="hits">19</td><td class="source"> if (isString(alias)) {</td></tr><tr class="hit"><td class="line">66</td><td class="hits">18</td><td class="source"> _alias[alias] = classFile;</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="hit"><td class="line">68</td><td class="hits">1</td><td class="source"> _alias = extend(_alias, alias);</td></tr><tr><td class="line">69</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">70</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">71</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">72</td><td class="hits"></td><td class="source">//常用类的基类</td></tr><tr class="hit"><td class="line">73</td><td class="hits">1</td><td class="source">['Cache', 'Behavior', 'Controller', 'Session', 'Model', 'Db'].forEach(function(item){</td></tr><tr class="hit"><td class="line">74</td><td class="hits">6</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">75</td><td class="hits">6</td><td class="source"> global[item] = function(super_, obj){</td></tr><tr class="hit"><td class="line">76</td><td class="hits">17</td><td class="source"> if (isString(super_)) {</td></tr><tr class="hit"><td class="line">77</td><td class="hits">1</td><td class="source"> return Class(obj, thinkRequire(super_));</td></tr><tr><td class="line">78</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">79</td><td class="hits">16</td><td class="source"> return Class(super_, thinkRequire(item));</td></tr><tr><td class="line">80</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">81</td><td class="hits"></td><td class="source">});</td></tr><tr><td class="line">82</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">84</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">85</td><td class="hits"></td><td class="source"> * 调用一个指定的行为</td></tr><tr><td class="line">86</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">87</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">88</td><td class="hits">1</td><td class="source">global.B = function(name, http, data){</td></tr><tr class="hit"><td class="line">89</td><td class="hits">6</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">90</td><td class="hits">6</td><td class="source"> if (typeof name === 'function') {</td></tr><tr class="miss"><td class="line">91</td><td class="hits">0</td><td class="source"> return name(http, data);</td></tr><tr><td class="line">92</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">93</td><td class="hits">6</td><td class="source"> return thinkRequire(name + 'Behavior')(http).run(data);</td></tr><tr><td class="line">94</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">95</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">97</td><td class="hits"></td><td class="source"> * 处理标签扩展</td></tr><tr><td class="line">98</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">99</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">100</td><td class="hits">1</td><td class="source">global.tag = function(name, http, data){</td></tr><tr class="hit"><td class="line">101</td><td class="hits">12</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">102</td><td class="hits">12</td><td class="source"> var sys_tags = (C('sys_tag.' + name) || []).slice();</td></tr><tr class="hit"><td class="line">103</td><td class="hits">12</td><td class="source"> var tags = (C('tag.' + name) || []).slice();</td></tr><tr><td class="line">104</td><td class="hits"></td><td class="source"> //tag处理的数据</td></tr><tr class="hit"><td class="line">105</td><td class="hits">12</td><td class="source"> http.tag_data = data;</td></tr><tr class="hit"><td class="line">106</td><td class="hits">12</td><td class="source"> if (tags.length) {</td></tr><tr class="miss"><td class="line">107</td><td class="hits">0</td><td class="source"> if (typeof tags[0] === 'boolean') {</td></tr><tr class="miss"><td class="line">108</td><td class="hits">0</td><td class="source"> var flag = tags.shift();</td></tr><tr><td class="line">109</td><td class="hits"></td><td class="source"> //为true时自定义tag覆盖sys tag, false是自定义tag添加到sys tag之前</td></tr><tr class="miss"><td class="line">110</td><td class="hits">0</td><td class="source"> if (!flag) {</td></tr><tr class="miss"><td class="line">111</td><td class="hits">0</td><td class="source"> tags = tags.concat(sys_tags);</td></tr><tr><td class="line">112</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source"> }else{</td></tr><tr><td class="line">114</td><td class="hits"></td><td class="source"> //默认是自定义tag放在sys tag之后</td></tr><tr class="miss"><td class="line">115</td><td class="hits">0</td><td class="source"> tags = sys_tags.concat(tags);</td></tr><tr><td class="line">116</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">117</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="hit"><td class="line">118</td><td class="hits">12</td><td class="source"> tags = sys_tags;</td></tr><tr><td class="line">119</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">120</td><td class="hits">12</td><td class="source"> function runBehavior(){</td></tr><tr class="hit"><td class="line">121</td><td class="hits">12</td><td class="source"> var behavior = tags.shift();</td></tr><tr class="hit"><td class="line">122</td><td class="hits">12</td><td class="source"> if (!behavior) {</td></tr><tr class="hit"><td class="line">123</td><td class="hits">6</td><td class="source"> return http.tag_data;</td></tr><tr><td class="line">124</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">125</td><td class="hits">6</td><td class="source"> var result = B(behavior, http, http.tag_data);</td></tr><tr class="hit"><td class="line">126</td><td class="hits">6</td><td class="source"> return getPromise(result).then(function(data){</td></tr><tr class="hit"><td class="line">127</td><td class="hits">6</td><td class="source"> if (data !== undefined) {</td></tr><tr class="hit"><td class="line">128</td><td class="hits">6</td><td class="source"> http.tag_data = data;</td></tr><tr><td class="line">129</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">130</td><td class="hits">6</td><td class="source"> return runBehavior();</td></tr><tr><td class="line">131</td><td class="hits"></td><td class="source"> })</td></tr><tr><td class="line">132</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">133</td><td class="hits">12</td><td class="source"> return getPromise(tags.length ? runBehavior() : http.tag_data);</td></tr><tr><td class="line">134</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">135</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">136</td><td class="hits"></td><td class="source"> * 配置读取和写入</td></tr><tr><td class="line">137</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">138</td><td class="hits">1</td><td class="source">var _config = {};</td></tr><tr class="hit"><td class="line">139</td><td class="hits">1</td><td class="source">global.C = function(name, value){</td></tr><tr class="hit"><td class="line">140</td><td class="hits">75</td><td class="source"> 'use strict';</td></tr><tr><td class="line">141</td><td class="hits"></td><td class="source"> //获取所有的配置</td></tr><tr class="hit"><td class="line">142</td><td class="hits">75</td><td class="source"> if (arguments.length === 0) {</td></tr><tr class="hit"><td class="line">143</td><td class="hits">1</td><td class="source"> return _config;</td></tr><tr><td class="line">144</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">145</td><td class="hits"></td><td class="source"> //清除所有的配置</td></tr><tr class="hit"><td class="line">146</td><td class="hits">74</td><td class="source"> if (name === null) {</td></tr><tr class="hit"><td class="line">147</td><td class="hits">1</td><td class="source"> _config = {};</td></tr><tr><td class="line">148</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">149</td><td class="hits">74</td><td class="source"> if (isString(name)) {</td></tr><tr class="hit"><td class="line">150</td><td class="hits">70</td><td class="source"> name = name.toLowerCase();</td></tr><tr class="hit"><td class="line">151</td><td class="hits">70</td><td class="source"> if (name.indexOf('.') === -1) {</td></tr><tr class="hit"><td class="line">152</td><td class="hits">46</td><td class="source"> if (value === undefined) {</td></tr><tr class="hit"><td class="line">153</td><td class="hits">45</td><td class="source"> return _config[name];</td></tr><tr><td class="line">154</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">155</td><td class="hits">1</td><td class="source"> _config[name] = value;</td></tr><tr class="hit"><td class="line">156</td><td class="hits">1</td><td class="source"> return;</td></tr><tr><td class="line">157</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">158</td><td class="hits">24</td><td class="source"> name = name.split('.');</td></tr><tr class="hit"><td class="line">159</td><td class="hits">24</td><td class="source"> if (value === undefined) {</td></tr><tr class="hit"><td class="line">160</td><td class="hits">24</td><td class="source"> value = _config[name[0]] || {};</td></tr><tr class="hit"><td class="line">161</td><td class="hits">24</td><td class="source"> return value[name[1]];</td></tr><tr><td class="line">162</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">163</td><td class="hits">0</td><td class="source"> if (!_config[name[0]]) {</td></tr><tr class="miss"><td class="line">164</td><td class="hits">0</td><td class="source"> _config[name[0]] = {};</td></tr><tr><td class="line">165</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">166</td><td class="hits">0</td><td class="source"> _config[name[0]][name[1]] = value;</td></tr><tr><td class="line">167</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="hit"><td class="line">168</td><td class="hits">4</td><td class="source"> _config = extend(_config, name);</td></tr><tr><td class="line">169</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">170</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">171</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">172</td><td class="hits"></td><td class="source"> * 实例化Controller类可以调用一个具体的Action</td></tr><tr><td class="line">173</td><td class="hits"></td><td class="source"> * A('Home/Index'), A('Admin/Index/test')</td></tr><tr><td class="line">174</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">175</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">176</td><td class="hits">1</td><td class="source">global.A = function(name, http, data){</td></tr><tr class="hit"><td class="line">177</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">178</td><td class="hits">1</td><td class="source"> if (name.indexOf('/') &gt; -1) {</td></tr><tr class="hit"><td class="line">179</td><td class="hits">1</td><td class="source"> name = name.split('/');</td></tr><tr class="miss"><td class="line">180</td><td class="hits">0</td><td class="source"> }else if (name.indexOf(':') &gt; -1) {</td></tr><tr class="miss"><td class="line">181</td><td class="hits">0</td><td class="source"> name = name.split(':');</td></tr><tr><td class="line">182</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">183</td><td class="hits">0</td><td class="source"> name = [name];</td></tr><tr><td class="line">184</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">185</td><td class="hits">1</td><td class="source"> var action;</td></tr><tr class="hit"><td class="line">186</td><td class="hits">1</td><td class="source"> if (name.length === 3) {</td></tr><tr class="miss"><td class="line">187</td><td class="hits">0</td><td class="source"> action = name.pop();</td></tr><tr><td class="line">188</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">189</td><td class="hits">1</td><td class="source"> var controller = name.pop() || http.controller;</td></tr><tr class="hit"><td class="line">190</td><td class="hits">1</td><td class="source"> var group = name.pop() || http.group;</td></tr><tr class="hit"><td class="line">191</td><td class="hits">1</td><td class="source"> var gm = ucfirst(group) + '/' + ucfirst(controller);</td></tr><tr class="hit"><td class="line">192</td><td class="hits">1</td><td class="source"> var path = getThinkRequirePath(gm + 'Controller');</td></tr><tr class="hit"><td class="line">193</td><td class="hits">1</td><td class="source"> if (path) {</td></tr><tr class="hit"><td class="line">194</td><td class="hits">1</td><td class="source"> var instance = require(path)(http);</td></tr><tr class="hit"><td class="line">195</td><td class="hits">1</td><td class="source"> if (action) {</td></tr><tr class="miss"><td class="line">196</td><td class="hits">0</td><td class="source"> action += C('action_suffix');</td></tr><tr class="miss"><td class="line">197</td><td class="hits">0</td><td class="source"> if (arguments.length === 2) {</td></tr><tr class="miss"><td class="line">198</td><td class="hits">0</td><td class="source"> data = [];</td></tr><tr class="miss"><td class="line">199</td><td class="hits">0</td><td class="source"> }else if (!isArray(data)) {</td></tr><tr class="miss"><td class="line">200</td><td class="hits">0</td><td class="source"> data = [data];</td></tr><tr><td class="line">201</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">202</td><td class="hits">0</td><td class="source"> return instance[action].apply(instance, data);</td></tr><tr><td class="line">203</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">204</td><td class="hits">1</td><td class="source"> return instance;</td></tr><tr><td class="line">205</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">206</td><td class="hits">0</td><td class="source"> return null;</td></tr><tr><td class="line">207</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">208</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">209</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">210</td><td class="hits"></td><td class="source"> * 快速文件读取和写入</td></tr><tr><td class="line">211</td><td class="hits"></td><td class="source"> * 默认写入到App/Runtime/Data目录下</td></tr><tr><td class="line">212</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">213</td><td class="hits">1</td><td class="source">global.F = function(name, value, rootPath){</td></tr><tr class="miss"><td class="line">214</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">215</td><td class="hits">0</td><td class="source"> if (rootPath === undefined) {</td></tr><tr class="miss"><td class="line">216</td><td class="hits">0</td><td class="source"> rootPath = DATA_PATH;</td></tr><tr><td class="line">217</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">218</td><td class="hits">0</td><td class="source"> var filePath = rootPath + '/' + name + '.json';</td></tr><tr class="miss"><td class="line">219</td><td class="hits">0</td><td class="source"> if (value !== undefined) {</td></tr><tr class="miss"><td class="line">220</td><td class="hits">0</td><td class="source"> mkdir(path.dirname(filePath));</td></tr><tr class="miss"><td class="line">221</td><td class="hits">0</td><td class="source"> fs.writeFile(filePath, JSON.stringify(value), function(){</td></tr><tr class="miss"><td class="line">222</td><td class="hits">0</td><td class="source"> chmod(filePath);</td></tr><tr><td class="line">223</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">224</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">225</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">226</td><td class="hits">0</td><td class="source"> if (isFile(filePath)) {</td></tr><tr class="miss"><td class="line">227</td><td class="hits">0</td><td class="source"> var content = getFileContent(filePath);</td></tr><tr class="miss"><td class="line">228</td><td class="hits">0</td><td class="source"> if (content) {</td></tr><tr class="miss"><td class="line">229</td><td class="hits">0</td><td class="source"> return JSON.parse(content);</td></tr><tr><td class="line">230</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">231</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">232</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">233</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">234</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">235</td><td class="hits"></td><td class="source"> * 实例化模型</td></tr><tr><td class="line">236</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">237</td><td class="hits">1</td><td class="source">global.D = function(name, tablePrefix, config){</td></tr><tr class="miss"><td class="line">238</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">239</td><td class="hits">0</td><td class="source"> if (name === undefined) {</td></tr><tr class="miss"><td class="line">240</td><td class="hits">0</td><td class="source"> return thinkRequire('Model')(name, tablePrefix, config);</td></tr><tr><td class="line">241</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">242</td><td class="hits">0</td><td class="source"> name = name.split(':');</td></tr><tr class="miss"><td class="line">243</td><td class="hits">0</td><td class="source"> var path = getThinkRequirePath(name[0] + 'Model');</td></tr><tr class="miss"><td class="line">244</td><td class="hits">0</td><td class="source"> if (path) {</td></tr><tr class="miss"><td class="line">245</td><td class="hits">0</td><td class="source"> return thinkRequire(name[0] + 'Model')(name[1], tablePrefix, config);</td></tr><tr><td class="line">246</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">247</td><td class="hits">0</td><td class="source"> return thinkRequire(name[1] === 'AdvModel' ? 'AdvModel' : 'Model')(name[0], tablePrefix, config);</td></tr><tr><td class="line">248</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">249</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">250</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">251</td><td class="hits"></td><td class="source"> * 实例化模型基类</td></tr><tr><td class="line">252</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">253</td><td class="hits"></td><td class="source"> * @param {[type]} tablePrefix [description]</td></tr><tr><td class="line">254</td><td class="hits"></td><td class="source"> * @param {[type]} config [description]</td></tr><tr><td class="line">255</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">256</td><td class="hits">1</td><td class="source">global.M = function(name, tablePrefix, config){</td></tr><tr class="miss"><td class="line">257</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">258</td><td class="hits">0</td><td class="source"> if (name === undefined) {</td></tr><tr class="miss"><td class="line">259</td><td class="hits">0</td><td class="source"> return thinkRequire('Model')(name, tablePrefix, config);</td></tr><tr><td class="line">260</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">261</td><td class="hits">0</td><td class="source"> name = name.split(':');</td></tr><tr class="miss"><td class="line">262</td><td class="hits">0</td><td class="source"> var model = name[1] === 'AdvModel' ? 'AdvModel' : 'Model';</td></tr><tr class="miss"><td class="line">263</td><td class="hits">0</td><td class="source"> return thinkRequire(model)(name[0], tablePrefix, config)</td></tr><tr><td class="line">264</td><td class="hits"></td><td class="source">}</td></tr><tr><td class="line">265</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">266</td><td class="hits"></td><td class="source"> * 缓存的设置和读取</td></tr><tr><td class="line">267</td><td class="hits"></td><td class="source"> * 获取返回的是一个promise</td></tr><tr><td class="line">268</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">269</td><td class="hits">1</td><td class="source">global.S = function(name, value, options){</td></tr><tr class="miss"><td class="line">270</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">271</td><td class="hits">0</td><td class="source"> if (options &amp;&amp; !isObject(options)) {</td></tr><tr class="miss"><td class="line">272</td><td class="hits">0</td><td class="source"> options = {timeout: options};</td></tr><tr><td class="line">273</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">274</td><td class="hits">0</td><td class="source"> options = options || {};</td></tr><tr class="miss"><td class="line">275</td><td class="hits">0</td><td class="source"> var type = options.type === undefined ? C('cache_type') : options.type;</td></tr><tr class="miss"><td class="line">276</td><td class="hits">0</td><td class="source"> var instance = thinkRequire(ucfirst(type.toLowerCase()) + 'Cache')(options);</td></tr><tr><td class="line">277</td><td class="hits"></td><td class="source"> //获取缓存</td></tr><tr class="miss"><td class="line">278</td><td class="hits">0</td><td class="source"> if (value === undefined) {</td></tr><tr class="miss"><td class="line">279</td><td class="hits">0</td><td class="source"> return instance.get(name);</td></tr><tr><td class="line">280</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">281</td><td class="hits"></td><td class="source"> //移除缓存</td></tr><tr class="miss"><td class="line">282</td><td class="hits">0</td><td class="source"> if (value === null) {</td></tr><tr class="miss"><td class="line">283</td><td class="hits">0</td><td class="source"> return instance.rm(name);</td></tr><tr><td class="line">284</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">285</td><td class="hits">0</td><td class="source"> return instance.set(name, value, options.timeout);</td></tr><tr><td class="line">286</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">287</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">288</td><td class="hits"></td><td class="source"> * 语言</td></tr><tr><td class="line">289</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">290</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">291</td><td class="hits">1</td><td class="source">global.L = function(name){</td></tr><tr class="miss"><td class="line">292</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">293</td><td class="hits">0</td><td class="source"> return name;</td></tr><tr><td class="line">294</td><td class="hits"></td><td class="source">};</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Conf/alias.js">/Users/welefen/Develop/git/thinkjs/lib/Conf/alias.js</h2><div id="stats" class="high"><div class="percentage">100%</div><div class="sloc">1</div><div class="hits">1</div><div class="misses">0</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * 模块别名,模块名到具体的路径,模块名不能有重复</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * 使用thinkRequire加载模块时有效</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> * @type {Object}</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">module.exports = {</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> Controller: THINK_LIB_PATH + '/Core/Controller.js',</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> App: THINK_LIB_PATH + '/Core/App.js',</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> Behavior: THINK_LIB_PATH + '/Util/Behavior.js',</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> Cache: THINK_LIB_PATH + '/Util/Cache.js',</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> Db: THINK_LIB_PATH + '/Core/Db.js',</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> Dispatcher: THINK_LIB_PATH + '/Core/Dispatcher.js',</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> Filter: THINK_LIB_PATH + '/Util/Filter.js',</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> Http: THINK_LIB_PATH + '/Core/Http.js',</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> //Log: THINK_LIB_PATH + '/Util/Log.js',</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> Model: THINK_LIB_PATH + '/Core/Model.js',</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> Session: THINK_LIB_PATH + '/Util/Session.js',</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> Think: THINK_LIB_PATH + '/Core/Think.js',</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> Valid: THINK_LIB_PATH + '/Util/Valid.js',</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> View: THINK_LIB_PATH + '/Core/View.js',</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> Cookie: THINK_LIB_PATH + '/Util/Cookie.js',</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> WebSocket: THINK_LIB_PATH + '/Util/WebSocket.js'</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source">};</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Conf/config.js">/Users/welefen/Develop/git/thinkjs/lib/Conf/config.js</h2><div id="stats" class="high"><div class="percentage">100%</div><div class="sloc">1</div><div class="hits">1</div><div class="misses">0</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * 框架默认配置</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * 可以在App/Conf/config.js里修改下面的配置值</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> * @type {Object}</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">module.exports = {</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> port: 8360, //监听端口</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> use_proxy: false, //是否使用代理访问nginx。开启后不能通过ip+端口直接访问</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> encoding: 'utf8', //输出数据的编码</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> url_pathname_prefix: '', //不解析的pathname前缀</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> url_pathname_suffix: '.html', //不解析的pathname后缀这样利于seo</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> app_tag_on: true, //是否支持标签功能</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> url_resource_on: true, //是否监听静态资源类请求</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> url_resource_reg: /^(resource\/|static\/|favicon\.ico)/, //判断是否是静态资源的正则</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> url_route_on: true, //是否开启自定义路由功能</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> post_json_content_type: ['application/json'], //post数据为json时的content-type</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> post_data_async: false, //POST提交的数据异步获取默认为同步获取</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> post_max_file_size: 1024 * 1024 * 1024, //上传文件大小限制默认1G</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> post_max_fields: 1000, //最大表单数</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> post_max_fields_size: 2 * 1024, //单个表单最大值</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> app_group_list: ['Home', 'Admin'], //分组列表</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> default_group: 'Home', //默认分组</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source"> default_controller: 'Index', //默认模块</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> default_action: 'index', //默认Action</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> call_controller: 'Home:Index:_404', //controller不存在时执行方法此配置表示调用Home分组下IndexController的_404Action方法</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> call_method: '__call', //当找不到方法时调用什么方法,这个方法存在时才有效</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> before_action_name: '__before', //调用一个action前调用的方法会将action名传递进去</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> after_action_name: '__after', //调用一个action之后调用的方法会将action名传递进去</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> url_params_bind: true, //方法参数绑定,将URL参数值绑定到action的参数上</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> action_suffix: 'Action', //action后缀</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> url_callback_name: 'callback', //jsonp格式的callback名字</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> json_content_type: 'application/json', //发送json时的content-type</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> auto_send_content_type: true, //是否自动发送Content-Type,默认值为`tpl_content_type`配置值</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> log_process_pid: true, //记录进程的id,方便其他脚本处理。</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> use_cluster: false, //是否使用cluster默认不使用0为cpu的数量可以自定义值</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> autoload_path: {}, //autoload查找的path用于thinkRequire加载自定义库的时候查找</td></tr><tr><td class="line">39</td><td class="hits"></td><td class="source"> create_server_fn: '', //自定义create server全局函数名可以在Common/common.js里实现</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">41</td><td class="hits"></td><td class="source"> load_ext_config: [], //加载额外的配置文件 CONF_PATH</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> load_ext_file: [], //加载额外的文件 COMMON_PATH</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> use_websocket: false, //是否使用websocket</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source"> websocket_allow_origin: '', //允许从那里发送过来的websocket可以是字符串、数组、回调函数为空表示不检测</td></tr><tr><td class="line">46</td><td class="hits"></td><td class="source"> websocket_sub_protocal: '', //websocket子协议可以是个字符串也可以是回调函数</td></tr><tr><td class="line">47</td><td class="hits"></td><td class="source"> websocket_message_handle: undefined, //websocket消息处理函数</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">49</td><td class="hits"></td><td class="source"> error_tpl_path: THINK_PATH + '/View/error.html', //错误页模版</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> error_no_key: 'errno', //错误number的key</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> error_no_default_value: 1000, //错误号默认值</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> error_msg_key: 'errmsg', //错误消息的key</td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> cookie_domain: '', //cookie有效域名</td></tr><tr><td class="line">55</td><td class="hits"></td><td class="source"> cookie_path: '/', //cookie路径</td></tr><tr><td class="line">56</td><td class="hits"></td><td class="source"> cookie_timeout: 0, //cookie失效时间0为浏览器关闭单位</td></tr><tr><td class="line">57</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">58</td><td class="hits"></td><td class="source"> session_name: 'thinkjs', //session对应的cookie名称</td></tr><tr><td class="line">59</td><td class="hits"></td><td class="source"> session_type: 'File', //session存储类型, 空为内存还可以为File</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> session_path: '', //File类型下文件存储位置默认为系统的tmp目录</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> session_options: {}, //session对应的cookie选项</td></tr><tr><td class="line">62</td><td class="hits"></td><td class="source"> session_sign: '', //session对应的cookie使用签名</td></tr><tr><td class="line">63</td><td class="hits"></td><td class="source"> session_timeout: 24 * 3600, //session失效时间单位</td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">65</td><td class="hits"></td><td class="source"> db_type: 'mysql', // 数据库类型</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> db_host: 'localhost', // 服务器地址</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> db_port: '', // 端口</td></tr><tr><td class="line">68</td><td class="hits"></td><td class="source"> db_name: '', // 数据库名</td></tr><tr><td class="line">69</td><td class="hits"></td><td class="source"> db_user: 'root', // 用户名</td></tr><tr><td class="line">70</td><td class="hits"></td><td class="source"> db_pwd: '', // 密码</td></tr><tr><td class="line">71</td><td class="hits"></td><td class="source"> db_prefix: 'think_', // 数据库表前缀</td></tr><tr><td class="line">72</td><td class="hits"></td><td class="source"> db_fieldtype_check: false, // 是否进行字段类型检查</td></tr><tr><td class="line">73</td><td class="hits"></td><td class="source"> db_fields_cache: true, // 启用字段缓存</td></tr><tr><td class="line">74</td><td class="hits"></td><td class="source"> db_charset: 'utf8', // 数据库编码默认采用utf8</td></tr><tr><td class="line">75</td><td class="hits"></td><td class="source"> db_nums_per_page: 20, //默认每页显示的条数</td></tr><tr><td class="line">76</td><td class="hits"></td><td class="source"> db_like_fields: [], //自动进行模糊查询,|连接,如: ['title', 'content']</td></tr><tr><td class="line">77</td><td class="hits"></td><td class="source"> db_cache_on: true, //是否启用查询缓存如果关闭那么cache方法则无效</td></tr><tr><td class="line">78</td><td class="hits"></td><td class="source"> db_cache_type: '', //缓存类型,默认为内存缓存</td></tr><tr><td class="line">79</td><td class="hits"></td><td class="source"> db_cache_path: CACHE_PATH + '/db', //缓存路径File类型下有效</td></tr><tr><td class="line">80</td><td class="hits"></td><td class="source"> db_cache_timeout: 3600, //缓存时间默认为1个小时</td></tr><tr><td class="line">81</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">82</td><td class="hits"></td><td class="source"> tpl_content_type: 'text/html', //模版输出类型</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> tpl_file_suffix: '.html', //模版文件名后缀</td></tr><tr><td class="line">84</td><td class="hits"></td><td class="source"> tpl_file_depr: '_', //controller和action之间的分隔符</td></tr><tr><td class="line">85</td><td class="hits"></td><td class="source"> tpl_engine_type: 'ejs', //模版引擎名称</td></tr><tr><td class="line">86</td><td class="hits"></td><td class="source"> tpl_engine_config: {}, </td></tr><tr><td class="line">87</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">88</td><td class="hits"></td><td class="source"> cache_type: 'File', //数据缓存类型</td></tr><tr><td class="line">89</td><td class="hits"></td><td class="source"> cache_timeout: 6 * 3600, //数据缓存有效期,单位: 秒</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source"> cache_path: CACHE_PATH, //缓存路径设置 (File缓存方式有效)</td></tr><tr><td class="line">91</td><td class="hits"></td><td class="source"> cache_file_suffix: '.json', //File缓存方式下文件后缀名</td></tr><tr><td class="line">92</td><td class="hits"></td><td class="source"> cache_gc_hour: [4], //缓存清除的时间点,数据为小时</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">94</td><td class="hits"></td><td class="source"> html_cache_on: false, //HTML静态缓存</td></tr><tr><td class="line">95</td><td class="hits"></td><td class="source"> html_cache_timeout: 3600, //缓存时间,单位为秒</td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source"> html_cache_rules: {}, //缓存规则</td></tr><tr><td class="line">97</td><td class="hits"></td><td class="source"> html_cache_path: CACHE_PATH + '/html',</td></tr><tr><td class="line">98</td><td class="hits"></td><td class="source"> html_cache_file_callback: undefined, //生成缓存文件的回调函数</td></tr><tr><td class="line">99</td><td class="hits"></td><td class="source"> html_cache_file_suffix: '.html', //缓存文件后缀名</td></tr><tr><td class="line">100</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">101</td><td class="hits"></td><td class="source"> memcache_host: '127.0.0.1', //memcache host</td></tr><tr><td class="line">102</td><td class="hits"></td><td class="source"> memcache_port: 11211, //memecache端口</td></tr><tr><td class="line">103</td><td class="hits"></td><td class="source">};</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Conf/mode.js">/Users/welefen/Develop/git/thinkjs/lib/Conf/mode.js</h2><div id="stats" class="high"><div class="percentage">100%</div><div class="sloc">1</div><div class="hits">1</div><div class="misses">0</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * 不同模式下的配置文件</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * 由于每个模式下的配置可能都比较少,所以放在一个文件里</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> * @type {Object}</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">module.exports = {</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> cli: {</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> use_cluster: false,</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> html_cache_on: false,</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> log_process_pid: false,</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> clear_require_cache: false</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> cli_debug: {</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> clear_require_cache: false</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source">};</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Conf/tag.js">/Users/welefen/Develop/git/thinkjs/lib/Conf/tag.js</h2><div id="stats" class="high"><div class="percentage">100%</div><div class="sloc">1</div><div class="hits">1</div><div class="misses">0</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * 系统标签配置</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * 可以在App/Conf/tag.js里进行修改</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> * @type {Object}</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">module.exports = {</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> //应用初始化</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> app_init: [],</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> //pathinfo解析</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> path_info: [],</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> //静态资源请求检测</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> resource_check: ['CheckResource'],</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> //路由检测</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> route_check: ['CheckRoute'],</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> //应用开始</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> app_begin: ['ReadHtmlCache'],</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> //action执行初始化</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> action_init: [],</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> //模版解析初始化</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> view_init: [],</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> //定位模版文件</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> view_template: ['LocationTemplate'],</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> //模版解析</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> view_parse: ['ParseTemplate'],</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source"> //模版内容过滤</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> view_filter: [],</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> //模版解析结束</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> view_end: ['WriteHtmlCache'],</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> //action结束</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> action_end: [],</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> //应用结束</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> app_end: []</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source">};</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/CheckResourceBehavior.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/CheckResourceBehavior.js</h2><div id="stats" class="low"><div class="percentage">48%</div><div class="sloc">25</div><div class="hits">12</div><div class="misses">13</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"><td class="line">1</td><td class="hits">1</td><td class="source">var fs = require('fs');</td></tr><tr class="hit"><td class="line">2</td><td class="hits">1</td><td class="source">var mime = require('mime');</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> * 静态资源请求</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source">module.exports = Behavior(function(){</td></tr><tr class="hit"><td class="line">8</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">9</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> options: {</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> 'url_resource_on': false</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> run: function(){</td></tr><tr class="hit"><td class="line">14</td><td class="hits">1</td><td class="source"> if (!RESOURCE_PATH || !this.options.url_resource_on || !this.http.pathname) {</td></tr><tr class="miss"><td class="line">15</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">17</td><td class="hits">1</td><td class="source"> var pathname = this.http.pathname;</td></tr><tr class="hit"><td class="line">18</td><td class="hits">1</td><td class="source"> if (pathname.indexOf('/') === 0) {</td></tr><tr class="hit"><td class="line">19</td><td class="hits">1</td><td class="source"> pathname = pathname.substr(1);</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">21</td><td class="hits">1</td><td class="source"> var reg = C('url_resource_reg');</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> //通过正则判断是否是静态资源请求</td></tr><tr class="hit"><td class="line">23</td><td class="hits">1</td><td class="source"> if (!reg.test(pathname)) {</td></tr><tr class="hit"><td class="line">24</td><td class="hits">1</td><td class="source"> return false;</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> </td></tr><tr class="miss"><td class="line">27</td><td class="hits">0</td><td class="source"> var file = RESOURCE_PATH + '/' + pathname;</td></tr><tr class="miss"><td class="line">28</td><td class="hits">0</td><td class="source"> var res = this.http.res;</td></tr><tr class="miss"><td class="line">29</td><td class="hits">0</td><td class="source"> if (fs.existsSync(file)) {</td></tr><tr class="miss"><td class="line">30</td><td class="hits">0</td><td class="source"> var contentType = mime.lookup(file);</td></tr><tr class="miss"><td class="line">31</td><td class="hits">0</td><td class="source"> var fileStream = fs.createReadStream(file);</td></tr><tr class="miss"><td class="line">32</td><td class="hits">0</td><td class="source"> res.setHeader('Content-Type', contentType + '; charset=' + C('encoding'));</td></tr><tr class="miss"><td class="line">33</td><td class="hits">0</td><td class="source"> fileStream.pipe(res);</td></tr><tr class="miss"><td class="line">34</td><td class="hits">0</td><td class="source"> fileStream.on('end', function(){</td></tr><tr class="miss"><td class="line">35</td><td class="hits">0</td><td class="source"> res.end();</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">38</td><td class="hits">0</td><td class="source"> res.statusCode = 404;</td></tr><tr class="miss"><td class="line">39</td><td class="hits">0</td><td class="source"> res.end();</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">41</td><td class="hits"></td><td class="source"> //返回一个pendding promise, 不让后续执行</td></tr><tr class="miss"><td class="line">42</td><td class="hits">0</td><td class="source"> return getDefer().promise;</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/CheckRouteBehavior.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/CheckRouteBehavior.js</h2><div id="stats" class="terrible"><div class="percentage">11%</div><div class="sloc">90</div><div class="hits">10</div><div class="misses">80</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * 检测路由行为</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * 通过自定义路由识别到对应的URL上</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">var url = require('url');</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source">var Dispatcher = thinkRequire('Dispatcher');</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">9</td><td class="hits">1</td><td class="source">module.exports = Behavior(function(){</td></tr><tr class="hit"><td class="line">10</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">11</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> options: {</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> 'url_route_on': false, //是否开启自定义URL路由</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> 'url_route_rules': [] //自定义URL路由规则</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> run: function(){</td></tr><tr class="hit"><td class="line">17</td><td class="hits">1</td><td class="source"> if (!this.options.url_route_on) {</td></tr><tr class="miss"><td class="line">18</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">20</td><td class="hits">1</td><td class="source"> var routes = this.options.url_route_rules;</td></tr><tr class="hit"><td class="line">21</td><td class="hits">1</td><td class="source"> var length = routes.length;</td></tr><tr class="hit"><td class="line">22</td><td class="hits">1</td><td class="source"> if (length === 0) {</td></tr><tr class="hit"><td class="line">23</td><td class="hits">1</td><td class="source"> return false;</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">25</td><td class="hits">0</td><td class="source"> var pathname = this.http.pathname;</td></tr><tr class="miss"><td class="line">26</td><td class="hits">0</td><td class="source"> var match;</td></tr><tr class="miss"><td class="line">27</td><td class="hits">0</td><td class="source"> for(var i = 0; i &lt; length; i++){</td></tr><tr class="miss"><td class="line">28</td><td class="hits">0</td><td class="source"> var route = routes[i];</td></tr><tr class="miss"><td class="line">29</td><td class="hits">0</td><td class="source"> var rule = route[0];</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> //正则路由</td></tr><tr class="miss"><td class="line">31</td><td class="hits">0</td><td class="source"> if (isRegexp(rule)) {</td></tr><tr class="miss"><td class="line">32</td><td class="hits">0</td><td class="source"> match = pathname.match(rule);</td></tr><tr class="miss"><td class="line">33</td><td class="hits">0</td><td class="source"> if (match) {</td></tr><tr class="miss"><td class="line">34</td><td class="hits">0</td><td class="source"> var result = this.parseRegExp(match, route[1], pathname);</td></tr><tr class="miss"><td class="line">35</td><td class="hits">0</td><td class="source"> if (result) {</td></tr><tr class="miss"><td class="line">36</td><td class="hits">0</td><td class="source"> return result;</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">39</td><td class="hits"></td><td class="source"> }else{</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> //字符串路由</td></tr><tr class="miss"><td class="line">41</td><td class="hits">0</td><td class="source"> match = this.checkUrlMatch(pathname, rule);</td></tr><tr class="miss"><td class="line">42</td><td class="hits">0</td><td class="source"> if (match) {</td></tr><tr class="miss"><td class="line">43</td><td class="hits">0</td><td class="source"> return this.parseRule(rule, route[1], pathname);</td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">46</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">47</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">49</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> * 解析字符串路由</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> * @param {[type]} rule [description]</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> * @param {[type]} route [description]</td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> * @param {[type]} pathname [description]</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">55</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">56</td><td class="hits"></td><td class="source"> parseRule: function(rule, route, pathname){</td></tr><tr class="miss"><td class="line">57</td><td class="hits">0</td><td class="source"> route = this.getRoute(route);</td></tr><tr class="miss"><td class="line">58</td><td class="hits">0</td><td class="source"> if (!route) {</td></tr><tr class="miss"><td class="line">59</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">61</td><td class="hits">0</td><td class="source"> pathname = pathname.split('/').filter(function(item){</td></tr><tr class="miss"><td class="line">62</td><td class="hits">0</td><td class="source"> return item.trim();</td></tr><tr><td class="line">63</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">64</td><td class="hits">0</td><td class="source"> rule = rule.split('/').filter(function(item){</td></tr><tr class="miss"><td class="line">65</td><td class="hits">0</td><td class="source"> return item.trim();</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">67</td><td class="hits">0</td><td class="source"> var matches = {};</td></tr><tr class="miss"><td class="line">68</td><td class="hits">0</td><td class="source"> rule.forEach(function(item){</td></tr><tr class="miss"><td class="line">69</td><td class="hits">0</td><td class="source"> var pathitem = pathname.shift();</td></tr><tr class="miss"><td class="line">70</td><td class="hits">0</td><td class="source"> if (item.indexOf(':') === 0) {</td></tr><tr class="miss"><td class="line">71</td><td class="hits">0</td><td class="source"> matches[item] = pathitem;</td></tr><tr><td class="line">72</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">73</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">74</td><td class="hits"></td><td class="source"> //将剩余的pathname分割为querystring</td></tr><tr class="miss"><td class="line">75</td><td class="hits">0</td><td class="source"> if (pathname.length) {</td></tr><tr class="miss"><td class="line">76</td><td class="hits">0</td><td class="source"> for(var i = 0,length = Math.ceil(pathname.length)/2; i &lt; length; i++){</td></tr><tr class="miss"><td class="line">77</td><td class="hits">0</td><td class="source"> this.http.get[pathname[i * 2]] = pathname[i * 2 + 1] || '';</td></tr><tr><td class="line">78</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">79</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">80</td><td class="hits">0</td><td class="source"> var values = Object.values(matches);</td></tr><tr class="miss"><td class="line">81</td><td class="hits">0</td><td class="source"> route = route.replace(/:(\d+)/g, function(a, b){</td></tr><tr class="miss"><td class="line">82</td><td class="hits">0</td><td class="source"> return values[b - 1] || '';</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">84</td><td class="hits">0</td><td class="source"> this.parseUrl(route);</td></tr><tr class="miss"><td class="line">85</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">86</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">87</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">88</td><td class="hits"></td><td class="source"> * 检测URL是否匹配</td></tr><tr><td class="line">89</td><td class="hits"></td><td class="source"> * @param {[type]} pathname [description]</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source"> * @param {[type]} rule [description]</td></tr><tr><td class="line">91</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">92</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source"> checkUrlMatch: function(pathname, rule){</td></tr><tr class="miss"><td class="line">94</td><td class="hits">0</td><td class="source"> pathname = pathname.split('/').filter(function(item){</td></tr><tr class="miss"><td class="line">95</td><td class="hits">0</td><td class="source"> return item.trim();</td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">97</td><td class="hits">0</td><td class="source"> rule = rule.split('/').filter(function(item){</td></tr><tr class="miss"><td class="line">98</td><td class="hits">0</td><td class="source"> return item.trim();</td></tr><tr><td class="line">99</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">100</td><td class="hits">0</td><td class="source"> return rule.every(function(item, i){</td></tr><tr class="miss"><td class="line">101</td><td class="hits">0</td><td class="source"> if (item.indexOf(':') === 0) {</td></tr><tr class="miss"><td class="line">102</td><td class="hits">0</td><td class="source"> if (item.indexOf('\\') &gt; -1) {</td></tr><tr class="miss"><td class="line">103</td><td class="hits">0</td><td class="source"> var type = item.substr(-1);</td></tr><tr class="miss"><td class="line">104</td><td class="hits">0</td><td class="source"> if (type === 'd' &amp;&amp; !isNumberString(pathname[i])) {</td></tr><tr class="miss"><td class="line">105</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">106</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">107</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">108</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">109</td><td class="hits">0</td><td class="source"> var pitem = pathname[i] || '';</td></tr><tr class="miss"><td class="line">110</td><td class="hits">0</td><td class="source"> if (pitem.toLowerCase() !== item.toLowerCase()) {</td></tr><tr class="miss"><td class="line">111</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">112</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">114</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">115</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">116</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">117</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">118</td><td class="hits"></td><td class="source"> * 解析转化后的url</td></tr><tr><td class="line">119</td><td class="hits"></td><td class="source"> * @param {[type]} urlInfo [description]</td></tr><tr><td class="line">120</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">121</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">122</td><td class="hits"></td><td class="source"> parseUrl: function(urlInfo){</td></tr><tr class="miss"><td class="line">123</td><td class="hits">0</td><td class="source"> urlInfo = url.parse(urlInfo, true);</td></tr><tr class="miss"><td class="line">124</td><td class="hits">0</td><td class="source"> if (urlInfo.query) {</td></tr><tr class="miss"><td class="line">125</td><td class="hits">0</td><td class="source"> for(var key in urlInfo.query){</td></tr><tr class="miss"><td class="line">126</td><td class="hits">0</td><td class="source"> if (urlInfo.query[key] || !(key in this.http.get)) {</td></tr><tr class="miss"><td class="line">127</td><td class="hits">0</td><td class="source"> this.http.get[key] = urlInfo.query[key];</td></tr><tr><td class="line">128</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">129</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">130</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">131</td><td class="hits">0</td><td class="source"> var pathname = urlInfo.pathname || '';</td></tr><tr><td class="line">132</td><td class="hits"></td><td class="source"> // 过滤调用pathname最后有/的情况</td></tr><tr class="miss"><td class="line">133</td><td class="hits">0</td><td class="source"> pathname = pathname.split('/').filter(function(item){</td></tr><tr class="miss"><td class="line">134</td><td class="hits">0</td><td class="source"> return item.trim();</td></tr><tr><td class="line">135</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">136</td><td class="hits">0</td><td class="source"> this.http.action = Dispatcher.getAction(pathname.pop());</td></tr><tr class="miss"><td class="line">137</td><td class="hits">0</td><td class="source"> this.http.controller = Dispatcher.getController(pathname.pop());</td></tr><tr class="miss"><td class="line">138</td><td class="hits">0</td><td class="source"> this.http.group = Dispatcher.getGroup(pathname.pop());</td></tr><tr><td class="line">139</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">140</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">141</td><td class="hits"></td><td class="source"> * 获取route</td></tr><tr><td class="line">142</td><td class="hits"></td><td class="source"> * @param {[type]} route [description]</td></tr><tr><td class="line">143</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">144</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">145</td><td class="hits"></td><td class="source"> getRoute: function(route){</td></tr><tr class="miss"><td class="line">146</td><td class="hits">0</td><td class="source"> if (isObject(route)) {</td></tr><tr><td class="line">147</td><td class="hits"></td><td class="source"> //对应的请求类型</td></tr><tr class="miss"><td class="line">148</td><td class="hits">0</td><td class="source"> for(var method in route){</td></tr><tr><td class="line">149</td><td class="hits"></td><td class="source"> //由于请求类型没有包含关系这里可以直接用indexOf判断</td></tr><tr class="miss"><td class="line">150</td><td class="hits">0</td><td class="source"> if (method.toUpperCase().indexOf(this.http.method) &gt; -1) {</td></tr><tr class="miss"><td class="line">151</td><td class="hits">0</td><td class="source"> return route[method];</td></tr><tr><td class="line">152</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">153</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">154</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">155</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">156</td><td class="hits">0</td><td class="source"> return route;</td></tr><tr><td class="line">157</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">158</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">159</td><td class="hits"></td><td class="source"> * 正则匹配路由</td></tr><tr><td class="line">160</td><td class="hits"></td><td class="source"> * @param {[type]} matches [description]</td></tr><tr><td class="line">161</td><td class="hits"></td><td class="source"> * @param {[type]} route [description]</td></tr><tr><td class="line">162</td><td class="hits"></td><td class="source"> * @param {[type]} pathname [description]</td></tr><tr><td class="line">163</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">164</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">165</td><td class="hits"></td><td class="source"> parseRegExp: function(matches, route, pathname){</td></tr><tr class="miss"><td class="line">166</td><td class="hits">0</td><td class="source"> route = this.getRoute(route);</td></tr><tr class="miss"><td class="line">167</td><td class="hits">0</td><td class="source"> if (!route) {</td></tr><tr class="miss"><td class="line">168</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">169</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">170</td><td class="hits">0</td><td class="source"> route = route.replace(/:(\d+)/g, function(a, b){</td></tr><tr class="miss"><td class="line">171</td><td class="hits">0</td><td class="source"> return matches[b] || '';</td></tr><tr><td class="line">172</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">173</td><td class="hits">0</td><td class="source"> pathname = pathname.replace(matches[0], '');</td></tr><tr class="miss"><td class="line">174</td><td class="hits">0</td><td class="source"> pathname = pathname.split('/').filter(function(item){</td></tr><tr class="miss"><td class="line">175</td><td class="hits">0</td><td class="source"> return item;</td></tr><tr><td class="line">176</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">177</td><td class="hits"></td><td class="source"> //将剩余的pathname分割为querystring</td></tr><tr class="miss"><td class="line">178</td><td class="hits">0</td><td class="source"> if (pathname.length) {</td></tr><tr class="miss"><td class="line">179</td><td class="hits">0</td><td class="source"> for(var i = 0,length = Math.ceil(pathname.length)/2; i &lt; length; i++){</td></tr><tr class="miss"><td class="line">180</td><td class="hits">0</td><td class="source"> this.http.get[pathname[i * 2]] = pathname[i * 2 + 1] || '';</td></tr><tr><td class="line">181</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">182</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">183</td><td class="hits">0</td><td class="source"> this.parseUrl(route);</td></tr><tr class="miss"><td class="line">184</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">185</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">186</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">187</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/DenyIpBehavior.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/DenyIpBehavior.js</h2><div id="stats" class="terrible"><div class="percentage">20%</div><div class="sloc">15</div><div class="hits">3</div><div class="misses">12</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * 阻止ip来源访问</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">module.exports = Behavior(function(){</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> options: {</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> deny_ip: [] //阻止的ip列表</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> run: function(){</td></tr><tr class="miss"><td class="line">12</td><td class="hits">0</td><td class="source"> if (this.options.deny_ip.length === 0) {</td></tr><tr class="miss"><td class="line">13</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">15</td><td class="hits">0</td><td class="source"> var clientIps = this.http.ip().split('.');</td></tr><tr class="miss"><td class="line">16</td><td class="hits">0</td><td class="source"> var flag = this.options.deny_ip.some(function(item){</td></tr><tr class="miss"><td class="line">17</td><td class="hits">0</td><td class="source"> return item.split('.').every(function(num, i){</td></tr><tr class="miss"><td class="line">18</td><td class="hits">0</td><td class="source"> if (num === '*' || num === clientIps[i]) {</td></tr><tr class="miss"><td class="line">19</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> //如果在阻止的ip在列表里则返回一个pendding promise让后面的代码不执行</td></tr><tr class="miss"><td class="line">24</td><td class="hits">0</td><td class="source"> if (flag) {</td></tr><tr class="miss"><td class="line">25</td><td class="hits">0</td><td class="source"> this.http.res.statusCode = 403;</td></tr><tr class="miss"><td class="line">26</td><td class="hits">0</td><td class="source"> this.http.res.end(); </td></tr><tr class="miss"><td class="line">27</td><td class="hits">0</td><td class="source"> return getDefer().promise;</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">29</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/LocationTemplateBehavior.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/LocationTemplateBehavior.js</h2><div id="stats" class="low"><div class="percentage">47%</div><div class="sloc">21</div><div class="hits">10</div><div class="misses">11</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * 定位模版的行为</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">module.exports = Behavior(function(){</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">8</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> run: function(templateFile){</td></tr><tr class="hit"><td class="line">10</td><td class="hits">1</td><td class="source"> if (!isFile(templateFile)) {</td></tr><tr class="hit"><td class="line">11</td><td class="hits">1</td><td class="source"> return this.parseTemplateFile(templateFile);</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> * 解析模版文件</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> * @param {[type]} templateFile [description]</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> parseTemplateFile: function(templateFile){</td></tr><tr class="hit"><td class="line">20</td><td class="hits">1</td><td class="source"> templateFile = templateFile || '';</td></tr><tr class="hit"><td class="line">21</td><td class="hits">1</td><td class="source"> if (!templateFile) {</td></tr><tr class="hit"><td class="line">22</td><td class="hits">1</td><td class="source"> templateFile = [</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> VIEW_PATH, '/', this.http.group, '/',</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> this.http.controller.toLowerCase(),</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source"> C('tpl_file_depr'),</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> this.http.action.toLowerCase(),</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> C('tpl_file_suffix')</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> ].join('');</td></tr><tr class="miss"><td class="line">29</td><td class="hits">0</td><td class="source"> }else if(templateFile.indexOf('/') &gt; -1){</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> //自动追加VIEW_PATH前缀</td></tr><tr class="miss"><td class="line">31</td><td class="hits">0</td><td class="source"> if (templateFile.indexOf('/') !== 0) {</td></tr><tr class="miss"><td class="line">32</td><td class="hits">0</td><td class="source"> templateFile = VIEW_PATH + '/' + templateFile;</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">34</td><td class="hits">0</td><td class="source"> }else if(templateFile.indexOf(C('tpl_file_suffix')) === -1){</td></tr><tr class="miss"><td class="line">35</td><td class="hits">0</td><td class="source"> var path = templateFile.split(':');</td></tr><tr class="miss"><td class="line">36</td><td class="hits">0</td><td class="source"> var action = path.pop();</td></tr><tr class="miss"><td class="line">37</td><td class="hits">0</td><td class="source"> var controller = path.pop() || this.http.controller.toLowerCase();</td></tr><tr class="miss"><td class="line">38</td><td class="hits">0</td><td class="source"> var group = ucfirst(path.pop()) || this.http.group;</td></tr><tr class="miss"><td class="line">39</td><td class="hits">0</td><td class="source"> templateFile = [</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> VIEW_PATH, '/', group, '/',</td></tr><tr><td class="line">41</td><td class="hits"></td><td class="source"> controller, </td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> C('tpl_file_depr'),</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> action,</td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> C('tpl_file_suffix')</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source"> ].join('');</td></tr><tr><td class="line">46</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">47</td><td class="hits">1</td><td class="source"> if (!isFile(templateFile)) {</td></tr><tr class="miss"><td class="line">48</td><td class="hits">0</td><td class="source"> console.log(templateFile + ' is not exist', this.http);</td></tr><tr class="miss"><td class="line">49</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">51</td><td class="hits">1</td><td class="source"> return templateFile;</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/ParseTemplateBehavior.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/ParseTemplateBehavior.js</h2><div id="stats" class="high"><div class="percentage">90%</div><div class="sloc">10</div><div class="hits">9</div><div class="misses">1</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * 调用对应的模版引擎解析模版</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">module.exports = Behavior(function(){</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> run: function(data){</td></tr><tr class="hit"><td class="line">9</td><td class="hits">1</td><td class="source"> var file = data.content || data.file;</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> //将模版文件路径写入到http对象上供writehtmlcache里使用</td></tr><tr class="hit"><td class="line">11</td><td class="hits">1</td><td class="source"> this.http.tpl_file = file;</td></tr><tr class="hit"><td class="line">12</td><td class="hits">1</td><td class="source"> var engine = C('tpl_engine_type');</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> //不使用模版引擎,直接返回文件内容</td></tr><tr class="hit"><td class="line">14</td><td class="hits">1</td><td class="source"> if (!engine) {</td></tr><tr class="miss"><td class="line">15</td><td class="hits">0</td><td class="source"> return getFileContent(file);</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">17</td><td class="hits">1</td><td class="source"> var engineClass = ucfirst(engine) + 'Template';</td></tr><tr class="hit"><td class="line">18</td><td class="hits">1</td><td class="source"> return thinkRequire(engineClass).fetch(file, data.var);</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/ReadHtmlCacheBehavior.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/ReadHtmlCacheBehavior.js</h2><div id="stats" class="terrible"><div class="percentage">10%</div><div class="sloc">64</div><div class="hits">7</div><div class="misses">57</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">//获取模版文件</td></tr><tr class="hit"><td class="line">2</td><td class="hits">1</td><td class="source">var getViewFile = thinkRequire('WriteHtmlCacheBehavior').getViewFile;</td></tr><tr class="hit"><td class="line">3</td><td class="hits">1</td><td class="source">var fs = require('fs');</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> * 读取HTML缓存</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">8</td><td class="hits">1</td><td class="source">module.exports = Behavior(function(){</td></tr><tr class="hit"><td class="line">9</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">10</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> options:{</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> 'html_cache_on': false, //是否开启缓存</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> 'html_cache_timeout': 3600, //缓存时间</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> 'html_cache_rules': {}, //缓存规则</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> 'html_cache_path': '',</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> 'html_cache_file_callback': undefined, //生成缓存文件的回调函数</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> 'html_cache_file_suffix': '.html', //缓存文件扩展名</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> run: function(){</td></tr><tr class="hit"><td class="line">20</td><td class="hits">1</td><td class="source"> if (!this.options.html_cache_on || isEmpty(this.options.html_cache_rules)) {</td></tr><tr class="hit"><td class="line">21</td><td class="hits">1</td><td class="source"> return false;</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">23</td><td class="hits">0</td><td class="source"> var cacheTime = this.getCacheTime();</td></tr><tr class="miss"><td class="line">24</td><td class="hits">0</td><td class="source"> if (cacheTime === false) {</td></tr><tr class="miss"><td class="line">25</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">27</td><td class="hits">0</td><td class="source"> if (this.checkCacheTime(cacheTime)) {</td></tr><tr class="miss"><td class="line">28</td><td class="hits">0</td><td class="source"> this.responseCacheContent();</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> //return a pending promise</td></tr><tr class="miss"><td class="line">30</td><td class="hits">0</td><td class="source"> return getDefer().promise;</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">32</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> * 返回缓存内容</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> responseCacheContent: function(){</td></tr><tr class="miss"><td class="line">39</td><td class="hits">0</td><td class="source"> var http = this.http;</td></tr><tr class="miss"><td class="line">40</td><td class="hits">0</td><td class="source"> var fileStream = fs.createReadStream(this.options.html_cache_path + '/' + http.html_filename);</td></tr><tr class="miss"><td class="line">41</td><td class="hits">0</td><td class="source"> http.setHeader('Content-Type', 'text/html');</td></tr><tr class="miss"><td class="line">42</td><td class="hits">0</td><td class="source"> http.sendTime('Exec-Time');</td></tr><tr class="miss"><td class="line">43</td><td class="hits">0</td><td class="source"> http.sendCookie();</td></tr><tr class="miss"><td class="line">44</td><td class="hits">0</td><td class="source"> fileStream.pipe(http.res);</td></tr><tr class="miss"><td class="line">45</td><td class="hits">0</td><td class="source"> fileStream.on('end', function(){</td></tr><tr class="miss"><td class="line">46</td><td class="hits">0</td><td class="source"> http.end();</td></tr><tr><td class="line">47</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">49</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> * 获取缓存时间</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> getCacheTime: function(){</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">55</td><td class="hits"></td><td class="source"> * rules数据格式</td></tr><tr><td class="line">56</td><td class="hits"></td><td class="source"> * {</td></tr><tr><td class="line">57</td><td class="hits"></td><td class="source"> * 'index:index': ['index_home', 1800, html_cache_callback]</td></tr><tr><td class="line">58</td><td class="hits"></td><td class="source"> * }</td></tr><tr><td class="line">59</td><td class="hits"></td><td class="source"> * @type {[type]}</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> */</td></tr><tr class="miss"><td class="line">61</td><td class="hits">0</td><td class="source"> var rules = this.options.html_cache_rules;</td></tr><tr class="miss"><td class="line">62</td><td class="hits">0</td><td class="source"> var group = this.http.group.toLowerCase();</td></tr><tr class="miss"><td class="line">63</td><td class="hits">0</td><td class="source"> var controller = this.http.controller.toLowerCase();</td></tr><tr class="miss"><td class="line">64</td><td class="hits">0</td><td class="source"> var action = this.http.action.toLowerCase();</td></tr><tr class="miss"><td class="line">65</td><td class="hits">0</td><td class="source"> var list = [</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> group + ':' + controller + ':' + action,</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> controller + ':' + action,</td></tr><tr><td class="line">68</td><td class="hits"></td><td class="source"> action,</td></tr><tr><td class="line">69</td><td class="hits"></td><td class="source"> '*'</td></tr><tr><td class="line">70</td><td class="hits"></td><td class="source"> ];</td></tr><tr class="miss"><td class="line">71</td><td class="hits">0</td><td class="source"> var html = [];</td></tr><tr class="miss"><td class="line">72</td><td class="hits">0</td><td class="source"> list.some(function(item){</td></tr><tr class="miss"><td class="line">73</td><td class="hits">0</td><td class="source"> if (item in rules) {</td></tr><tr class="miss"><td class="line">74</td><td class="hits">0</td><td class="source"> html = rules[item];</td></tr><tr class="miss"><td class="line">75</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">76</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">77</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">78</td><td class="hits">0</td><td class="source"> if (isEmpty(html)) {</td></tr><tr class="miss"><td class="line">79</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">80</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">81</td><td class="hits">0</td><td class="source"> if (!isArray(html)) {</td></tr><tr class="miss"><td class="line">82</td><td class="hits">0</td><td class="source"> html = [html];</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">84</td><td class="hits">0</td><td class="source"> var rule = html[0];</td></tr><tr><td class="line">85</td><td class="hits"></td><td class="source"> //将cookie变量传递进去</td></tr><tr class="miss"><td class="line">86</td><td class="hits">0</td><td class="source"> var cookiePars = {};</td></tr><tr class="miss"><td class="line">87</td><td class="hits">0</td><td class="source"> for(var name in this.http.cookie){</td></tr><tr class="miss"><td class="line">88</td><td class="hits">0</td><td class="source"> cookiePars['cookie.' + name] = this.http.cookie[name];</td></tr><tr><td class="line">89</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">90</td><td class="hits">0</td><td class="source"> var pars = extend({}, this.http.get, cookiePars, {</td></tr><tr><td class="line">91</td><td class="hits"></td><td class="source"> ':group': group,</td></tr><tr><td class="line">92</td><td class="hits"></td><td class="source"> ':controller': controller,</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source"> ':action': action</td></tr><tr><td class="line">94</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">95</td><td class="hits">0</td><td class="source"> rule = rule.replace(/\{([\w\:]+)\}/g, function(a, name){</td></tr><tr class="miss"><td class="line">96</td><td class="hits">0</td><td class="source"> return pars[name] || '';</td></tr><tr><td class="line">97</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">98</td><td class="hits">0</td><td class="source"> var callback = html[2] || C('html_cache_file_callback') || this.getCacheFilename;</td></tr><tr class="miss"><td class="line">99</td><td class="hits">0</td><td class="source"> var filename = callback(rule, this.http) + this.options.html_cache_file_suffix;</td></tr><tr><td class="line">100</td><td class="hits"></td><td class="source"> //静态缓存文件名</td></tr><tr class="miss"><td class="line">101</td><td class="hits">0</td><td class="source"> this.http.html_filename = filename;</td></tr><tr class="miss"><td class="line">102</td><td class="hits">0</td><td class="source"> var cacheTime = html[1] || this.options.html_cache_timeout;</td></tr><tr class="miss"><td class="line">103</td><td class="hits">0</td><td class="source"> return cacheTime;</td></tr><tr><td class="line">104</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">105</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">106</td><td class="hits"></td><td class="source"> * </td></tr><tr><td class="line">107</td><td class="hits"></td><td class="source"> * @param {[type]} key [description]</td></tr><tr><td class="line">108</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">109</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">110</td><td class="hits"></td><td class="source"> getCacheFilename: function(key){</td></tr><tr class="miss"><td class="line">111</td><td class="hits">0</td><td class="source"> var value = md5(key);</td></tr><tr class="miss"><td class="line">112</td><td class="hits">0</td><td class="source"> return value.substr(0, 1) + '/' + value;</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">114</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">115</td><td class="hits"></td><td class="source"> * [checkCacheTime description]</td></tr><tr><td class="line">116</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">117</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">118</td><td class="hits"></td><td class="source"> checkCacheTime: function(cacheTime){</td></tr><tr class="miss"><td class="line">119</td><td class="hits">0</td><td class="source"> var cacheFile = this.options.html_cache_path + '/' + this.http.html_filename;</td></tr><tr class="miss"><td class="line">120</td><td class="hits">0</td><td class="source"> if (!isFile(cacheFile)) {</td></tr><tr class="miss"><td class="line">121</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">122</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">123</td><td class="hits">0</td><td class="source"> var cacheFileMtime = fs.statSync(cacheFile).mtime.getTime();</td></tr><tr class="miss"><td class="line">124</td><td class="hits">0</td><td class="source"> var tplFile = getViewFile(this.http);</td></tr><tr class="miss"><td class="line">125</td><td class="hits">0</td><td class="source"> if (tplFile) {</td></tr><tr class="miss"><td class="line">126</td><td class="hits">0</td><td class="source"> if (!isFile(tplFile)) {</td></tr><tr class="miss"><td class="line">127</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">128</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">129</td><td class="hits">0</td><td class="source"> var tplFileMtime = fs.statSync(tplFile).mtime.getTime();</td></tr><tr><td class="line">130</td><td class="hits"></td><td class="source"> //模版文件有更新</td></tr><tr class="miss"><td class="line">131</td><td class="hits">0</td><td class="source"> if (tplFileMtime &gt; cacheFileMtime) {</td></tr><tr class="miss"><td class="line">132</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">133</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">134</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">135</td><td class="hits">0</td><td class="source"> if (Date.now() &gt; (cacheFileMtime + cacheTime * 1000)) {</td></tr><tr class="miss"><td class="line">136</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">137</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">138</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">139</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">140</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">141</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/WriteHtmlCacheBehavior.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Behavior/WriteHtmlCacheBehavior.js</h2><div id="stats" class="low"><div class="percentage">45%</div><div class="sloc">20</div><div class="hits">9</div><div class="misses">11</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * 模版文件列表</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @type {Object}</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">var path = require('path');</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">var fs = require('fs');</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">8</td><td class="hits">1</td><td class="source">var tplFiles = {};</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> * 写入html缓存</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">13</td><td class="hits">1</td><td class="source">module.exports = Behavior(function(){</td></tr><tr class="hit"><td class="line">14</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">15</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> options: {</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> 'html_cache_on': false, //是否开启缓存</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> 'html_cache_path': ''</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> run: function(content){</td></tr><tr class="hit"><td class="line">21</td><td class="hits">1</td><td class="source"> if (!this.options.html_cache_on || !this.http.html_filename) {</td></tr><tr class="hit"><td class="line">22</td><td class="hits">1</td><td class="source"> return content;</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">24</td><td class="hits">0</td><td class="source"> this.recordViewFile();</td></tr><tr class="miss"><td class="line">25</td><td class="hits">0</td><td class="source"> var file = this.options.html_cache_path + '/' + this.http.html_filename;</td></tr><tr class="miss"><td class="line">26</td><td class="hits">0</td><td class="source"> mkdir(path.dirname(file));</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> //异步方式写入缓存</td></tr><tr class="miss"><td class="line">28</td><td class="hits">0</td><td class="source"> fs.writeFile(file, content);</td></tr><tr class="miss"><td class="line">29</td><td class="hits">0</td><td class="source"> return content;</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> * 记录模版文件名</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> recordViewFile: function(){</td></tr><tr class="miss"><td class="line">36</td><td class="hits">0</td><td class="source"> var tplFile = this.http.tpl_file;</td></tr><tr class="miss"><td class="line">37</td><td class="hits">0</td><td class="source"> var key = this.http.group + ':' + this.http.controller + ':' + this.http.action;</td></tr><tr class="miss"><td class="line">38</td><td class="hits">0</td><td class="source"> tplFiles[key] = tplFile;</td></tr><tr><td class="line">39</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">41</td><td class="hits"></td><td class="source">});</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> * 获取模版文件</td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> * @param {[type]} http [description]</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">46</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">47</td><td class="hits">1</td><td class="source">module.exports.getViewFile = function(http){</td></tr><tr class="miss"><td class="line">48</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">49</td><td class="hits">0</td><td class="source"> var key = http.group + ':' + http.controller + ':' + http.action;</td></tr><tr class="miss"><td class="line">50</td><td class="hits">0</td><td class="source"> return tplFiles[key];</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source">};</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/App.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/App.js</h2><div id="stats" class="low"><div class="percentage">48%</div><div class="sloc">141</div><div class="hits">68</div><div class="misses">73</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"><td class="line">1</td><td class="hits">1</td><td class="source">var cluster = require('cluster');</td></tr><tr class="hit"><td class="line">2</td><td class="hits">1</td><td class="source">var fs = require('fs');</td></tr><tr class="hit"><td class="line">3</td><td class="hits">1</td><td class="source">var domain = require('domain');</td></tr><tr class="hit"><td class="line">4</td><td class="hits">1</td><td class="source">var thinkHttp = thinkRequire('Http');</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">var Dispatcher = thinkRequire('Dispatcher');</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> * 应用程序</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> * @type {Object}</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">11</td><td class="hits">1</td><td class="source">var App = module.exports = Class(function(){</td></tr><tr class="hit"><td class="line">12</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> //controller和action的校验正则</td></tr><tr class="hit"><td class="line">14</td><td class="hits">1</td><td class="source"> var nameReg = /^[A-Za-z\_](\w)*$/;</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> //注释的正则</td></tr><tr class="hit"><td class="line">16</td><td class="hits">1</td><td class="source"> var commentReg = /((\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s))/mg;</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> //获取形参的正则</td></tr><tr class="hit"><td class="line">18</td><td class="hits">1</td><td class="source"> var parsReg = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">20</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> init: function(http){</td></tr><tr class="hit"><td class="line">22</td><td class="hits">1</td><td class="source"> this.http = http;</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source"> * 解析路由</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> dispatch: function(){</td></tr><tr class="hit"><td class="line">29</td><td class="hits">1</td><td class="source"> return Dispatcher(this.http).run();</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> * 获取controller</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> getController: function(){</td></tr><tr class="hit"><td class="line">36</td><td class="hits">1</td><td class="source"> var group = this.http.group;</td></tr><tr class="hit"><td class="line">37</td><td class="hits">1</td><td class="source"> var controller = '';</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> //检测controller名</td></tr><tr class="hit"><td class="line">39</td><td class="hits">1</td><td class="source"> if (nameReg.test(this.http.controller)) {</td></tr><tr class="hit"><td class="line">40</td><td class="hits">1</td><td class="source"> controller = A(group + '/' + this.http.controller, this.http);</td></tr><tr class="hit"><td class="line">41</td><td class="hits">1</td><td class="source"> if (controller) {</td></tr><tr class="hit"><td class="line">42</td><td class="hits">1</td><td class="source"> return controller;</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source"> //controller不存在时调用的魔术方法</td></tr><tr class="miss"><td class="line">46</td><td class="hits">0</td><td class="source"> var controllerConf = C('call_controller');</td></tr><tr class="miss"><td class="line">47</td><td class="hits">0</td><td class="source"> if (controllerConf) {</td></tr><tr class="miss"><td class="line">48</td><td class="hits">0</td><td class="source"> if (isString(controllerConf)) {</td></tr><tr class="miss"><td class="line">49</td><td class="hits">0</td><td class="source"> controllerConf = controllerConf.split(':');</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">51</td><td class="hits">0</td><td class="source"> var action = Dispatcher.getAction(controllerConf.pop());</td></tr><tr class="miss"><td class="line">52</td><td class="hits">0</td><td class="source"> controller = Dispatcher.getController(controllerConf.pop());</td></tr><tr class="miss"><td class="line">53</td><td class="hits">0</td><td class="source"> group = Dispatcher.getGroup(controllerConf.pop());</td></tr><tr class="miss"><td class="line">54</td><td class="hits">0</td><td class="source"> controller = A(group + '/' + controller, this.http);</td></tr><tr class="miss"><td class="line">55</td><td class="hits">0</td><td class="source"> if (controller &amp;&amp; isFunction(controller[action + C('action_suffix')])) {</td></tr><tr class="miss"><td class="line">56</td><td class="hits">0</td><td class="source"> this.http.group = group;</td></tr><tr class="miss"><td class="line">57</td><td class="hits">0</td><td class="source"> this.http.controller = controller;</td></tr><tr class="miss"><td class="line">58</td><td class="hits">0</td><td class="source"> this.http.action = action;</td></tr><tr class="miss"><td class="line">59</td><td class="hits">0</td><td class="source"> return controller;</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">62</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">63</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> * 执行</td></tr><tr><td class="line">65</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> exec: function(){</td></tr><tr class="hit"><td class="line">68</td><td class="hits">1</td><td class="source"> var controller = this.getController();</td></tr><tr class="hit"><td class="line">69</td><td class="hits">1</td><td class="source"> if (!controller) {</td></tr><tr class="miss"><td class="line">70</td><td class="hits">0</td><td class="source"> var err = new Error('Controller `' + this.http.controller + '` not found. ' + this.http.pathname);</td></tr><tr class="miss"><td class="line">71</td><td class="hits">0</td><td class="source"> return getPromise(err, true);</td></tr><tr><td class="line">72</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">73</td><td class="hits">1</td><td class="source"> var self = this;</td></tr><tr class="hit"><td class="line">74</td><td class="hits">1</td><td class="source"> var action = this.http.action;</td></tr><tr class="hit"><td class="line">75</td><td class="hits">1</td><td class="source"> var act = action;</td></tr><tr><td class="line">76</td><td class="hits"></td><td class="source"> //添加action后缀</td></tr><tr class="hit"><td class="line">77</td><td class="hits">1</td><td class="source"> action += C('action_suffix') || '';</td></tr><tr><td class="line">78</td><td class="hits"></td><td class="source"> //检测action名</td></tr><tr class="hit"><td class="line">79</td><td class="hits">1</td><td class="source"> if (!nameReg.test(action)) {</td></tr><tr class="miss"><td class="line">80</td><td class="hits">0</td><td class="source"> return getPromise(new Error('action `' + act + '` is not valid. ' + this.http.pathname), true);</td></tr><tr><td class="line">81</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">82</td><td class="hits">1</td><td class="source"> var initReturnPromise = getPromise(controller.__initReturn);</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> //对应的action方法存在</td></tr><tr class="hit"><td class="line">84</td><td class="hits">1</td><td class="source"> if (isFunction(controller[action])) {</td></tr><tr><td class="line">85</td><td class="hits"></td><td class="source"> //方法参数自动绑定,直接从形参里拿到对应的值</td></tr><tr class="hit"><td class="line">86</td><td class="hits">1</td><td class="source"> if (C('url_params_bind')) {</td></tr><tr class="hit"><td class="line">87</td><td class="hits">1</td><td class="source"> var toString = controller[action].toString().replace(commentReg, '');</td></tr><tr class="hit"><td class="line">88</td><td class="hits">1</td><td class="source"> var match = toString.match(parsReg)[1].split(/,/).filter(function(item){</td></tr><tr class="hit"><td class="line">89</td><td class="hits">1</td><td class="source"> return item;</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">91</td><td class="hits"></td><td class="source"> //匹配到形参</td></tr><tr class="hit"><td class="line">92</td><td class="hits">1</td><td class="source"> if (match &amp;&amp; match.length) {</td></tr><tr class="miss"><td class="line">93</td><td class="hits">0</td><td class="source"> return initReturnPromise.then(function(){</td></tr><tr class="miss"><td class="line">94</td><td class="hits">0</td><td class="source"> var data = match.map(function(item){</td></tr><tr class="miss"><td class="line">95</td><td class="hits">0</td><td class="source"> return self.http.post[item] || self.http.get[item] || '';</td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">97</td><td class="hits">0</td><td class="source"> return self.execAction(controller, action, act, data);</td></tr><tr><td class="line">98</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">99</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">100</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">101</td><td class="hits">1</td><td class="source"> return initReturnPromise.then(function(){</td></tr><tr class="hit"><td class="line">102</td><td class="hits">1</td><td class="source"> return self.execAction(controller, action, act);</td></tr><tr><td class="line">103</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">104</td><td class="hits"></td><td class="source"> }else{</td></tr><tr><td class="line">105</td><td class="hits"></td><td class="source"> //当指定的方法不存在时,调用魔术方法</td></tr><tr><td class="line">106</td><td class="hits"></td><td class="source"> //默认为__call方法</td></tr><tr class="miss"><td class="line">107</td><td class="hits">0</td><td class="source"> var callMethod = C('call_method');</td></tr><tr class="miss"><td class="line">108</td><td class="hits">0</td><td class="source"> if (callMethod &amp;&amp; isFunction(controller[callMethod])) {</td></tr><tr class="miss"><td class="line">109</td><td class="hits">0</td><td class="source"> return initReturnPromise.then(function(){</td></tr><tr class="miss"><td class="line">110</td><td class="hits">0</td><td class="source"> return controller[callMethod](act, action);</td></tr><tr><td class="line">111</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">112</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">114</td><td class="hits">0</td><td class="source"> return getPromise(new Error('action `' + action + '` not found. ' + self.http.pathname), true);</td></tr><tr><td class="line">115</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">116</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">117</td><td class="hits"></td><td class="source"> * 执行一个action, 支持before和after的统一操作</td></tr><tr><td class="line">118</td><td class="hits"></td><td class="source"> * 不对每个action都增加一个before和after而是使用统一的策略</td></tr><tr><td class="line">119</td><td class="hits"></td><td class="source"> * 默认before和after调用名__before和__after</td></tr><tr><td class="line">120</td><td class="hits"></td><td class="source"> * @param {[type]} controller [description]</td></tr><tr><td class="line">121</td><td class="hits"></td><td class="source"> * @param {[type]} action [description]</td></tr><tr><td class="line">122</td><td class="hits"></td><td class="source"> * @param {[type]} act [description]</td></tr><tr><td class="line">123</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">124</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">125</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">126</td><td class="hits"></td><td class="source"> execAction: function(controller, action, act, data){</td></tr><tr class="hit"><td class="line">127</td><td class="hits">1</td><td class="source"> var promise = getPromise();</td></tr><tr><td class="line">128</td><td class="hits"></td><td class="source"> //before action</td></tr><tr class="hit"><td class="line">129</td><td class="hits">1</td><td class="source"> var before = C('before_action_name');</td></tr><tr class="hit"><td class="line">130</td><td class="hits">1</td><td class="source"> if (before &amp;&amp; isFunction(controller[before])) {</td></tr><tr class="miss"><td class="line">131</td><td class="hits">0</td><td class="source"> promise = getPromise(controller[before](act, action));</td></tr><tr><td class="line">132</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">133</td><td class="hits">1</td><td class="source"> return promise.then(function(){</td></tr><tr class="hit"><td class="line">134</td><td class="hits">1</td><td class="source"> if (data) {</td></tr><tr class="miss"><td class="line">135</td><td class="hits">0</td><td class="source"> return controller[action].apply(controller, data)</td></tr><tr><td class="line">136</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="hit"><td class="line">137</td><td class="hits">1</td><td class="source"> return controller[action]()</td></tr><tr><td class="line">138</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">139</td><td class="hits"></td><td class="source"> }).then(function(){</td></tr><tr><td class="line">140</td><td class="hits"></td><td class="source"> //after action</td></tr><tr class="hit"><td class="line">141</td><td class="hits">1</td><td class="source"> var after = C('after_action_name');</td></tr><tr class="hit"><td class="line">142</td><td class="hits">1</td><td class="source"> if (after &amp;&amp; isFunction(controller[after])) {</td></tr><tr class="miss"><td class="line">143</td><td class="hits">0</td><td class="source"> return controller[after](act, action);</td></tr><tr><td class="line">144</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">145</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">146</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">147</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">148</td><td class="hits"></td><td class="source"> * 发送错误信息</td></tr><tr><td class="line">149</td><td class="hits"></td><td class="source"> * @param {[type]} error [description]</td></tr><tr><td class="line">150</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">151</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">152</td><td class="hits"></td><td class="source"> sendError: function(error){</td></tr><tr class="miss"><td class="line">153</td><td class="hits">0</td><td class="source"> var message = isError(error) ? error.stack : error;</td></tr><tr class="miss"><td class="line">154</td><td class="hits">0</td><td class="source"> var http = this.http;</td></tr><tr class="miss"><td class="line">155</td><td class="hits">0</td><td class="source"> console.log(message);</td></tr><tr class="miss"><td class="line">156</td><td class="hits">0</td><td class="source"> if (!http.res) {</td></tr><tr class="miss"><td class="line">157</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">158</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">159</td><td class="hits">0</td><td class="source"> if (APP_DEBUG) {</td></tr><tr class="miss"><td class="line">160</td><td class="hits">0</td><td class="source"> http.res.statusCode = 500;</td></tr><tr class="miss"><td class="line">161</td><td class="hits">0</td><td class="source"> http.res.end(message);</td></tr><tr><td class="line">162</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">163</td><td class="hits">0</td><td class="source"> http.res.statusCode = 500;</td></tr><tr class="miss"><td class="line">164</td><td class="hits">0</td><td class="source"> http.setHeader('Content-Type', 'text/html; charset=' + C('encoding'));</td></tr><tr class="miss"><td class="line">165</td><td class="hits">0</td><td class="source"> var readStream = fs.createReadStream(C('error_tpl_path'));</td></tr><tr class="miss"><td class="line">166</td><td class="hits">0</td><td class="source"> readStream.pipe(http.res);</td></tr><tr class="miss"><td class="line">167</td><td class="hits">0</td><td class="source"> readStream.on('end', function(){</td></tr><tr class="miss"><td class="line">168</td><td class="hits">0</td><td class="source"> http.res.end();</td></tr><tr><td class="line">169</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">170</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">171</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">172</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">173</td><td class="hits"></td><td class="source">});</td></tr><tr><td class="line">174</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">175</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">176</td><td class="hits"></td><td class="source"> * run</td></tr><tr><td class="line">177</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">178</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">179</td><td class="hits">1</td><td class="source">App.run = function(){</td></tr><tr class="hit"><td class="line">180</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">181</td><td class="hits">1</td><td class="source"> return App.mode[APP_MODE]();</td></tr><tr><td class="line">182</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">183</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">184</td><td class="hits"></td><td class="source"> * 不同模式下的run</td></tr><tr><td class="line">185</td><td class="hits"></td><td class="source"> * @type {Object}</td></tr><tr><td class="line">186</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">187</td><td class="hits">1</td><td class="source">App.mode = {</td></tr><tr><td class="line">188</td><td class="hits"></td><td class="source"> //命令行模式</td></tr><tr><td class="line">189</td><td class="hits"></td><td class="source"> cli: function(){</td></tr><tr class="hit"><td class="line">190</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">191</td><td class="hits">1</td><td class="source"> var defaultHttp = thinkHttp.getDefaultHttp(process.argv[2]);</td></tr><tr class="hit"><td class="line">192</td><td class="hits">1</td><td class="source"> thinkHttp(defaultHttp.req, defaultHttp.res).run(App.listener);</td></tr><tr><td class="line">193</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">194</td><td class="hits"></td><td class="source"> //HTTP模式</td></tr><tr><td class="line">195</td><td class="hits"></td><td class="source"> http: function(){</td></tr><tr class="miss"><td class="line">196</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">197</td><td class="hits">0</td><td class="source"> var clusterNums = C('use_cluster');</td></tr><tr><td class="line">198</td><td class="hits"></td><td class="source"> //不使用cluster</td></tr><tr class="miss"><td class="line">199</td><td class="hits">0</td><td class="source"> if (!clusterNums) {</td></tr><tr class="miss"><td class="line">200</td><td class="hits">0</td><td class="source"> return App.createServer();</td></tr><tr><td class="line">201</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">202</td><td class="hits"></td><td class="source"> //使用cpu的个数</td></tr><tr class="miss"><td class="line">203</td><td class="hits">0</td><td class="source"> if (clusterNums === true) {</td></tr><tr class="miss"><td class="line">204</td><td class="hits">0</td><td class="source"> clusterNums = require('os').cpus().length;</td></tr><tr><td class="line">205</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">206</td><td class="hits">0</td><td class="source"> if (cluster.isMaster) {</td></tr><tr class="miss"><td class="line">207</td><td class="hits">0</td><td class="source"> for (var i = 0; i &lt; clusterNums; i++) {</td></tr><tr class="miss"><td class="line">208</td><td class="hits">0</td><td class="source"> cluster.fork();</td></tr><tr><td class="line">209</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">210</td><td class="hits">0</td><td class="source"> cluster.on('exit', function(worker) {</td></tr><tr class="miss"><td class="line">211</td><td class="hits">0</td><td class="source"> console.log('worker ' + worker.process.pid + ' died');</td></tr><tr class="miss"><td class="line">212</td><td class="hits">0</td><td class="source"> process.nextTick(function(){</td></tr><tr class="miss"><td class="line">213</td><td class="hits">0</td><td class="source"> cluster.fork();</td></tr><tr><td class="line">214</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">215</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">216</td><td class="hits"></td><td class="source"> }else {</td></tr><tr class="miss"><td class="line">217</td><td class="hits">0</td><td class="source"> App.createServer();</td></tr><tr><td class="line">218</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">219</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">220</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">221</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">222</td><td class="hits"></td><td class="source"> * 创建服务</td></tr><tr><td class="line">223</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">224</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">225</td><td class="hits">1</td><td class="source">App.createServer = function(){</td></tr><tr class="miss"><td class="line">226</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr><td class="line">227</td><td class="hits"></td><td class="source"> //自定义创建server</td></tr><tr class="miss"><td class="line">228</td><td class="hits">0</td><td class="source"> var createServerFn = C('create_server_fn');</td></tr><tr class="miss"><td class="line">229</td><td class="hits">0</td><td class="source"> if (createServerFn) {</td></tr><tr class="miss"><td class="line">230</td><td class="hits">0</td><td class="source"> if (isFunction(createServerFn)) {</td></tr><tr class="miss"><td class="line">231</td><td class="hits">0</td><td class="source"> return createServerFn(App);</td></tr><tr class="miss"><td class="line">232</td><td class="hits">0</td><td class="source"> }else if (isFunction(global[createServerFn])) {</td></tr><tr class="miss"><td class="line">233</td><td class="hits">0</td><td class="source"> return global[createServerFn](App);</td></tr><tr><td class="line">234</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">235</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">236</td><td class="hits">0</td><td class="source"> var server = require('http').createServer(function (req, res) {</td></tr><tr class="miss"><td class="line">237</td><td class="hits">0</td><td class="source"> thinkHttp(req, res).run(App.listener);</td></tr><tr><td class="line">238</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">239</td><td class="hits">0</td><td class="source"> thinkRequire('WebSocket')(server, App).run();</td></tr><tr class="miss"><td class="line">240</td><td class="hits">0</td><td class="source"> server.listen(C('port'));</td></tr><tr><td class="line">241</td><td class="hits"></td><td class="source">}</td></tr><tr><td class="line">242</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">243</td><td class="hits"></td><td class="source"> * 监听回调函数</td></tr><tr><td class="line">244</td><td class="hits"></td><td class="source"> * @param {[type]} http [description]</td></tr><tr><td class="line">245</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">246</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">247</td><td class="hits">1</td><td class="source">App.listener = function(http){</td></tr><tr class="hit"><td class="line">248</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr><td class="line">249</td><td class="hits"></td><td class="source"> //自动发送thinkjs和版本的header</td></tr><tr class="hit"><td class="line">250</td><td class="hits">1</td><td class="source"> http.setHeader('X-Powered-By', 'thinkjs-' + THINK_VERSION);</td></tr><tr><td class="line">251</td><td class="hits"></td><td class="source"> //禁止远程直接用带端口的访问,websocket下允许</td></tr><tr class="hit"><td class="line">252</td><td class="hits">1</td><td class="source"> if (C('use_proxy') &amp;&amp; http.host !== http.hostname &amp;&amp; !http.websocket) {</td></tr><tr class="miss"><td class="line">253</td><td class="hits">0</td><td class="source"> http.res.statusCode = 403;</td></tr><tr class="miss"><td class="line">254</td><td class="hits">0</td><td class="source"> http.res.end();</td></tr><tr class="miss"><td class="line">255</td><td class="hits">0</td><td class="source"> return getDefer().promise;</td></tr><tr><td class="line">256</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">257</td><td class="hits">1</td><td class="source"> var instance = App(http);</td></tr><tr class="hit"><td class="line">258</td><td class="hits">1</td><td class="source"> var domainInstance = domain.create();</td></tr><tr class="hit"><td class="line">259</td><td class="hits">1</td><td class="source"> var deferred = getDefer();</td></tr><tr class="hit"><td class="line">260</td><td class="hits">1</td><td class="source"> domainInstance.on('error', function(err){</td></tr><tr class="miss"><td class="line">261</td><td class="hits">0</td><td class="source"> instance.sendError(err);</td></tr><tr class="miss"><td class="line">262</td><td class="hits">0</td><td class="source"> deferred.reject(err);</td></tr><tr><td class="line">263</td><td class="hits"></td><td class="source"> });</td></tr><tr class="hit"><td class="line">264</td><td class="hits">1</td><td class="source"> domainInstance.run(function(){</td></tr><tr class="hit"><td class="line">265</td><td class="hits">1</td><td class="source"> return tag('app_init', http).then(function(){</td></tr><tr class="hit"><td class="line">266</td><td class="hits">1</td><td class="source"> return instance.dispatch();</td></tr><tr><td class="line">267</td><td class="hits"></td><td class="source"> }).then(function(){</td></tr><tr class="hit"><td class="line">268</td><td class="hits">1</td><td class="source"> return tag('app_begin', http);</td></tr><tr><td class="line">269</td><td class="hits"></td><td class="source"> }).then(function(){</td></tr><tr class="hit"><td class="line">270</td><td class="hits">1</td><td class="source"> return tag('action_init', http);</td></tr><tr><td class="line">271</td><td class="hits"></td><td class="source"> }).then(function(){</td></tr><tr class="hit"><td class="line">272</td><td class="hits">1</td><td class="source"> return instance.exec();</td></tr><tr><td class="line">273</td><td class="hits"></td><td class="source"> }).then(function(){</td></tr><tr class="hit"><td class="line">274</td><td class="hits">1</td><td class="source"> return tag('app_end', http);</td></tr><tr><td class="line">275</td><td class="hits"></td><td class="source"> }).catch(function(err){</td></tr><tr class="miss"><td class="line">276</td><td class="hits">0</td><td class="source"> instance.sendError(err);</td></tr><tr><td class="line">277</td><td class="hits"></td><td class="source"> }).then(function(){</td></tr><tr class="hit"><td class="line">278</td><td class="hits">1</td><td class="source"> deferred.resolve();</td></tr><tr><td class="line">279</td><td class="hits"></td><td class="source"> })</td></tr><tr><td class="line">280</td><td class="hits"></td><td class="source"> });</td></tr><tr class="hit"><td class="line">281</td><td class="hits">1</td><td class="source"> return deferred.promise;</td></tr><tr><td class="line">282</td><td class="hits"></td><td class="source">};</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Controller.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Controller.js</h2><div id="stats" class="terrible"><div class="percentage">11%</div><div class="sloc">151</div><div class="hits">18</div><div class="misses">133</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * Controller 基类</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">var fs = require('fs');</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">var path = require('path');</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source">var url = require('url');</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">9</td><td class="hits">1</td><td class="source">module.exports = Class(function() {</td></tr><tr class="hit"><td class="line">10</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> //callback正则</td></tr><tr class="hit"><td class="line">12</td><td class="hits">1</td><td class="source"> var callbackReg = /[^\w\.]/g;</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">14</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> * 初始化执行方法</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> * @param {[type]} http [description]</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> init: function(http) {</td></tr><tr class="hit"><td class="line">21</td><td class="hits">1</td><td class="source"> this.http = http;</td></tr><tr class="hit"><td class="line">22</td><td class="hits">1</td><td class="source"> this.view = null;</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> //将http数据打到模版里</td></tr><tr class="hit"><td class="line">24</td><td class="hits">1</td><td class="source"> this.assign('http', this.http);</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source"> //将配置信息打到模版里</td></tr><tr class="hit"><td class="line">26</td><td class="hits">1</td><td class="source"> this.assign('config', C());</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> //设置变量别名</td></tr><tr class="hit"><td class="line">28</td><td class="hits">1</td><td class="source"> this.set = this.assign;</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> * 获取客户端的ip</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> ip: function() {</td></tr><tr class="miss"><td class="line">35</td><td class="hits">0</td><td class="source"> return this.http.ip();</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> * 实例化View类</td></tr><tr><td class="line">39</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">41</td><td class="hits"></td><td class="source"> initView: function() {</td></tr><tr class="hit"><td class="line">42</td><td class="hits">3</td><td class="source"> if (!this.view) {</td></tr><tr class="hit"><td class="line">43</td><td class="hits">1</td><td class="source"> this.view = thinkRequire('View')(this.http);</td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">45</td><td class="hits">3</td><td class="source"> return this.view;</td></tr><tr><td class="line">46</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">47</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> * 是否是GET请求</td></tr><tr><td class="line">49</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> isGet: function() {</td></tr><tr class="miss"><td class="line">52</td><td class="hits">0</td><td class="source"> return this.http.method === 'GET';</td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">55</td><td class="hits"></td><td class="source"> * 是否是POST请求</td></tr><tr><td class="line">56</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">57</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">58</td><td class="hits"></td><td class="source"> isPost: function() {</td></tr><tr class="miss"><td class="line">59</td><td class="hits">0</td><td class="source"> return this.http.method === 'POST';</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">62</td><td class="hits"></td><td class="source"> * 是否是特定METHOD请求</td></tr><tr><td class="line">63</td><td class="hits"></td><td class="source"> * @param {[type]} method [description]</td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">65</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> isMethod: function(method) {</td></tr><tr class="miss"><td class="line">67</td><td class="hits">0</td><td class="source"> return this.http.method === method.toUpperCase();</td></tr><tr><td class="line">68</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">69</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">70</td><td class="hits"></td><td class="source"> * 是否是AJAX请求</td></tr><tr><td class="line">71</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">72</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">73</td><td class="hits"></td><td class="source"> isAjax: function(method) {</td></tr><tr><td class="line">74</td><td class="hits"></td><td class="source"> //请求类型判断</td></tr><tr class="miss"><td class="line">75</td><td class="hits">0</td><td class="source"> if (method &amp;&amp; this.http.method !== method) {</td></tr><tr class="miss"><td class="line">76</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">77</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">78</td><td class="hits">0</td><td class="source"> return this.header('x-requested-with') === 'XMLHttpRequest';</td></tr><tr><td class="line">79</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">80</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">81</td><td class="hits"></td><td class="source"> * 是否是websocket请求</td></tr><tr><td class="line">82</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">84</td><td class="hits"></td><td class="source"> isWebSocket: function(){</td></tr><tr class="miss"><td class="line">85</td><td class="hits">0</td><td class="source"> return !!this.http.websocket;</td></tr><tr><td class="line">86</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">87</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">88</td><td class="hits"></td><td class="source"> * 是否是命令行模式</td></tr><tr><td class="line">89</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">91</td><td class="hits"></td><td class="source"> isCli: function(){</td></tr><tr class="miss"><td class="line">92</td><td class="hits">0</td><td class="source"> return APP_MODE === 'cli';</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">94</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">95</td><td class="hits"></td><td class="source"> * 是否是jsonp接口</td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">97</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">98</td><td class="hits"></td><td class="source"> isJsonp: function(name){</td></tr><tr class="miss"><td class="line">99</td><td class="hits">0</td><td class="source"> name = name || C('url_callback_name');</td></tr><tr class="miss"><td class="line">100</td><td class="hits">0</td><td class="source"> return !!this.http.get(name);</td></tr><tr><td class="line">101</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">102</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">103</td><td class="hits"></td><td class="source"> * 获取QUERY参数</td></tr><tr><td class="line">104</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">105</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">106</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">107</td><td class="hits"></td><td class="source"> get: function(name) {</td></tr><tr class="miss"><td class="line">108</td><td class="hits">0</td><td class="source"> if (name === undefined) {</td></tr><tr class="miss"><td class="line">109</td><td class="hits">0</td><td class="source"> return this.http.get;</td></tr><tr><td class="line">110</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">111</td><td class="hits">0</td><td class="source"> return this.http.get[name] || '';</td></tr><tr><td class="line">112</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">114</td><td class="hits"></td><td class="source"> * 获取POST参数</td></tr><tr><td class="line">115</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">116</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">117</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">118</td><td class="hits"></td><td class="source"> post: function(name) {</td></tr><tr class="miss"><td class="line">119</td><td class="hits">0</td><td class="source"> var http = this.http;</td></tr><tr class="miss"><td class="line">120</td><td class="hits">0</td><td class="source"> if (http.postPromise) {</td></tr><tr class="miss"><td class="line">121</td><td class="hits">0</td><td class="source"> return http.postPromise.then(function(data){</td></tr><tr class="miss"><td class="line">122</td><td class="hits">0</td><td class="source"> return name ? (data[name] || '') : data;</td></tr><tr><td class="line">123</td><td class="hits"></td><td class="source"> })</td></tr><tr><td class="line">124</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">125</td><td class="hits">0</td><td class="source"> return name ? (http.post[name] || '') : http.post;</td></tr><tr><td class="line">126</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">127</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">128</td><td class="hits"></td><td class="source"> * 获取参数</td></tr><tr><td class="line">129</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">130</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">131</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">132</td><td class="hits"></td><td class="source"> param: function(name) {</td></tr><tr class="miss"><td class="line">133</td><td class="hits">0</td><td class="source"> return this.post(name) || this.get(name);</td></tr><tr><td class="line">134</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">135</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">136</td><td class="hits"></td><td class="source"> * 获取上传的文件</td></tr><tr><td class="line">137</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">138</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">139</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">140</td><td class="hits"></td><td class="source"> file: function(name) {</td></tr><tr class="miss"><td class="line">141</td><td class="hits">0</td><td class="source"> var http = this.http;</td></tr><tr class="miss"><td class="line">142</td><td class="hits">0</td><td class="source"> if (http.postPromise) {</td></tr><tr class="miss"><td class="line">143</td><td class="hits">0</td><td class="source"> return http.postPromise.then(function(){</td></tr><tr class="miss"><td class="line">144</td><td class="hits">0</td><td class="source"> return name ? (http.file[name] || '') : http.file;</td></tr><tr><td class="line">145</td><td class="hits"></td><td class="source"> })</td></tr><tr><td class="line">146</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">147</td><td class="hits">0</td><td class="source"> return name ? (http.file[name] || '') : http.file;</td></tr><tr><td class="line">148</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">149</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">150</td><td class="hits"></td><td class="source"> * header操作</td></tr><tr><td class="line">151</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">152</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">153</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">154</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">155</td><td class="hits"></td><td class="source"> header: function(name, value) {</td></tr><tr class="miss"><td class="line">156</td><td class="hits">0</td><td class="source"> if (name === undefined) {</td></tr><tr class="miss"><td class="line">157</td><td class="hits">0</td><td class="source"> return this.http.headers;</td></tr><tr class="miss"><td class="line">158</td><td class="hits">0</td><td class="source"> }else if (isObject(name)) {</td></tr><tr class="miss"><td class="line">159</td><td class="hits">0</td><td class="source"> for (var key in name) {</td></tr><tr class="miss"><td class="line">160</td><td class="hits">0</td><td class="source"> this.header(key, name[key]);</td></tr><tr><td class="line">161</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">162</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr class="miss"><td class="line">163</td><td class="hits">0</td><td class="source"> }else if (value !== undefined) {</td></tr><tr class="miss"><td class="line">164</td><td class="hits">0</td><td class="source"> this.http.setHeader(name, value);</td></tr><tr class="miss"><td class="line">165</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">166</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">167</td><td class="hits">0</td><td class="source"> return this.http.getHeader(name);</td></tr><tr><td class="line">168</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">169</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">170</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">171</td><td class="hits"></td><td class="source"> * 获取userAgent</td></tr><tr><td class="line">172</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">173</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">174</td><td class="hits"></td><td class="source"> userAgent: function(){</td></tr><tr class="miss"><td class="line">175</td><td class="hits">0</td><td class="source"> return this.http.headers['user-agent'] || '';</td></tr><tr><td class="line">176</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">177</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">178</td><td class="hits"></td><td class="source"> * 获取referrer</td></tr><tr><td class="line">179</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">180</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">181</td><td class="hits"></td><td class="source"> referer: function(host){</td></tr><tr class="miss"><td class="line">182</td><td class="hits">0</td><td class="source"> var referer = this.http.headers.referer || this.http.headers.referfer || '';</td></tr><tr class="miss"><td class="line">183</td><td class="hits">0</td><td class="source"> if (!referer || !host) {</td></tr><tr class="miss"><td class="line">184</td><td class="hits">0</td><td class="source"> return referer;</td></tr><tr><td class="line">185</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">186</td><td class="hits">0</td><td class="source"> var info = url.parse(referer);</td></tr><tr class="miss"><td class="line">187</td><td class="hits">0</td><td class="source"> return info.hostname;</td></tr><tr><td class="line">188</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">189</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">190</td><td class="hits"></td><td class="source"> * cookie操作</td></tr><tr><td class="line">191</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">192</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">193</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">194</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">195</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">196</td><td class="hits"></td><td class="source"> cookie: function(name, value, options) {</td></tr><tr class="miss"><td class="line">197</td><td class="hits">0</td><td class="source"> if (value !== undefined) {</td></tr><tr class="miss"><td class="line">198</td><td class="hits">0</td><td class="source"> this.http.setCookie(name, value, options);</td></tr><tr class="miss"><td class="line">199</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">200</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">201</td><td class="hits">0</td><td class="source"> return name === undefined ? this.http.cookie : (this.http.cookie[name] || '');</td></tr><tr><td class="line">202</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">203</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">204</td><td class="hits"></td><td class="source"> * session</td></tr><tr><td class="line">205</td><td class="hits"></td><td class="source"> * 如果是get操作则返回一个promise</td></tr><tr><td class="line">206</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">207</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">208</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">209</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">210</td><td class="hits"></td><td class="source"> session: function(name, value) {</td></tr><tr class="miss"><td class="line">211</td><td class="hits">0</td><td class="source"> thinkRequire('Session').start(this.http);</td></tr><tr class="miss"><td class="line">212</td><td class="hits">0</td><td class="source"> var instance = this.http.session;</td></tr><tr class="miss"><td class="line">213</td><td class="hits">0</td><td class="source"> if (name === undefined) {</td></tr><tr class="miss"><td class="line">214</td><td class="hits">0</td><td class="source"> return instance.rm();</td></tr><tr><td class="line">215</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">216</td><td class="hits">0</td><td class="source"> if (value !== undefined) {</td></tr><tr class="miss"><td class="line">217</td><td class="hits">0</td><td class="source"> return instance.set(name, value);</td></tr><tr><td class="line">218</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">219</td><td class="hits">0</td><td class="source"> return instance.get(name);</td></tr><tr><td class="line">220</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">221</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">222</td><td class="hits"></td><td class="source"> * 跳转返回一个pendding promise阻止后面继续执行</td></tr><tr><td class="line">223</td><td class="hits"></td><td class="source"> * @param {[type]} url [description]</td></tr><tr><td class="line">224</td><td class="hits"></td><td class="source"> * @param {[type]} code [description]</td></tr><tr><td class="line">225</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">226</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">227</td><td class="hits"></td><td class="source"> redirect: function(url, code) {</td></tr><tr class="miss"><td class="line">228</td><td class="hits">0</td><td class="source"> this.http.redirect(url, code);</td></tr><tr class="miss"><td class="line">229</td><td class="hits">0</td><td class="source"> return getDefer().promise;</td></tr><tr><td class="line">230</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">231</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">232</td><td class="hits"></td><td class="source"> * 赋值变量到模版</td></tr><tr><td class="line">233</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">234</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">235</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">236</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">237</td><td class="hits"></td><td class="source"> assign: function(name, value) {</td></tr><tr class="hit"><td class="line">238</td><td class="hits">2</td><td class="source"> if (arguments.length === 1) {</td></tr><tr class="miss"><td class="line">239</td><td class="hits">0</td><td class="source"> return this.initView().assign(name);</td></tr><tr><td class="line">240</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">241</td><td class="hits">2</td><td class="source"> return this.initView().assign(name, value);</td></tr><tr><td class="line">242</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">243</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">244</td><td class="hits"></td><td class="source"> * 获取解析后的模版内容</td></tr><tr><td class="line">245</td><td class="hits"></td><td class="source"> * @param {[type]} templateFile [description]</td></tr><tr><td class="line">246</td><td class="hits"></td><td class="source"> * @param {[type]} content [description]</td></tr><tr><td class="line">247</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">248</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">249</td><td class="hits"></td><td class="source"> fetch: function(templateFile, content) {</td></tr><tr class="miss"><td class="line">250</td><td class="hits">0</td><td class="source"> return this.initView().fetch(templateFile, content);</td></tr><tr><td class="line">251</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">252</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">253</td><td class="hits"></td><td class="source"> * 输出模版内容</td></tr><tr><td class="line">254</td><td class="hits"></td><td class="source"> * @param {[type]} templateFile [description]</td></tr><tr><td class="line">255</td><td class="hits"></td><td class="source"> * @param {[type]} charset [description]</td></tr><tr><td class="line">256</td><td class="hits"></td><td class="source"> * @param {[type]} contentType [description]</td></tr><tr><td class="line">257</td><td class="hits"></td><td class="source"> * @param {[type]} content [description]</td></tr><tr><td class="line">258</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">259</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">260</td><td class="hits"></td><td class="source"> display: function(templateFile, charset, contentType, content) {</td></tr><tr class="hit"><td class="line">261</td><td class="hits">1</td><td class="source"> return this.initView().display(templateFile, charset, contentType, content);</td></tr><tr><td class="line">262</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">263</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">264</td><td class="hits"></td><td class="source"> * 调用另一个controll里的aciton</td></tr><tr><td class="line">265</td><td class="hits"></td><td class="source"> * 可以跨分组</td></tr><tr><td class="line">266</td><td class="hits"></td><td class="source"> * A('Admin/Test/index')</td></tr><tr><td class="line">267</td><td class="hits"></td><td class="source"> * @param {[type]} action [description]</td></tr><tr><td class="line">268</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">269</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">270</td><td class="hits"></td><td class="source"> action: function(action, data) {</td></tr><tr><td class="line">271</td><td class="hits"></td><td class="source"> //自动补group</td></tr><tr class="miss"><td class="line">272</td><td class="hits">0</td><td class="source"> if (action.split(':').length === 2) {</td></tr><tr class="miss"><td class="line">273</td><td class="hits">0</td><td class="source"> action = this.http.group + ':' + action;</td></tr><tr><td class="line">274</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">275</td><td class="hits">0</td><td class="source"> return A(action, this.http, data);</td></tr><tr><td class="line">276</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">277</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">278</td><td class="hits"></td><td class="source"> * jsonp格式输出</td></tr><tr><td class="line">279</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">280</td><td class="hits"></td><td class="source"> * @param {[type]} jsonp [description]</td></tr><tr><td class="line">281</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">282</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">283</td><td class="hits"></td><td class="source"> jsonp: function(data) {</td></tr><tr class="miss"><td class="line">284</td><td class="hits">0</td><td class="source"> this.type(C('json_content_type'));</td></tr><tr class="miss"><td class="line">285</td><td class="hits">0</td><td class="source"> var callback = this.get(C('url_callback_name'));</td></tr><tr><td class="line">286</td><td class="hits"></td><td class="source"> //过滤callback值里的非法字符</td></tr><tr class="miss"><td class="line">287</td><td class="hits">0</td><td class="source"> callback = callback.replace(callbackReg, '');</td></tr><tr class="miss"><td class="line">288</td><td class="hits">0</td><td class="source"> if (callback) {</td></tr><tr class="miss"><td class="line">289</td><td class="hits">0</td><td class="source"> this.echo(callback + '(');</td></tr><tr class="miss"><td class="line">290</td><td class="hits">0</td><td class="source"> this.echo(data);</td></tr><tr class="miss"><td class="line">291</td><td class="hits">0</td><td class="source"> this.end(')');</td></tr><tr><td class="line">292</td><td class="hits"></td><td class="source"> } else {</td></tr><tr class="miss"><td class="line">293</td><td class="hits">0</td><td class="source"> this.end(data);</td></tr><tr><td class="line">294</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">295</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">296</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">297</td><td class="hits"></td><td class="source"> * json格式输出</td></tr><tr><td class="line">298</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">299</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">300</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">301</td><td class="hits"></td><td class="source"> json: function(data){</td></tr><tr class="miss"><td class="line">302</td><td class="hits">0</td><td class="source"> this.type(C('json_content_type'));</td></tr><tr class="miss"><td class="line">303</td><td class="hits">0</td><td class="source"> return this.end(data);</td></tr><tr><td class="line">304</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">305</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">306</td><td class="hits"></td><td class="source"> * 设置http响应状态码</td></tr><tr><td class="line">307</td><td class="hits"></td><td class="source"> * @param {[type]} status [description]</td></tr><tr><td class="line">308</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">309</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">310</td><td class="hits"></td><td class="source"> status: function(status) {</td></tr><tr class="miss"><td class="line">311</td><td class="hits">0</td><td class="source"> var res = this.http.res;</td></tr><tr class="miss"><td class="line">312</td><td class="hits">0</td><td class="source"> if (!res.headersSent) {</td></tr><tr class="miss"><td class="line">313</td><td class="hits">0</td><td class="source"> res.statusCode = status || 404;</td></tr><tr><td class="line">314</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">315</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">316</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">317</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">318</td><td class="hits"></td><td class="source"> * 阻止访问</td></tr><tr><td class="line">319</td><td class="hits"></td><td class="source"> * @param {[type]} status [description]</td></tr><tr><td class="line">320</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">321</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">322</td><td class="hits"></td><td class="source"> deny: function(status){</td></tr><tr class="miss"><td class="line">323</td><td class="hits">0</td><td class="source"> var res = this.http.res;</td></tr><tr class="miss"><td class="line">324</td><td class="hits">0</td><td class="source"> if (!res.headersSent) {</td></tr><tr class="miss"><td class="line">325</td><td class="hits">0</td><td class="source"> res.statusCode = status || 403;</td></tr><tr class="miss"><td class="line">326</td><td class="hits">0</td><td class="source"> this.http.end();</td></tr><tr><td class="line">327</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">328</td><td class="hits">0</td><td class="source"> return getDefer().promise;</td></tr><tr><td class="line">329</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">330</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">331</td><td class="hits"></td><td class="source"> * 输出内容</td></tr><tr><td class="line">332</td><td class="hits"></td><td class="source"> * 自动JSON.stringify</td></tr><tr><td class="line">333</td><td class="hits"></td><td class="source"> * 自定将数字等转化为字符串</td></tr><tr><td class="line">334</td><td class="hits"></td><td class="source"> * @param {[type]} obj [description]</td></tr><tr><td class="line">335</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">336</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">337</td><td class="hits"></td><td class="source"> echo: function(obj, encoding) {</td></tr><tr><td class="line">338</td><td class="hits"></td><td class="source"> //自动发送Content-Type的header</td></tr><tr class="miss"><td class="line">339</td><td class="hits">0</td><td class="source"> if (C('auto_send_content_type')) {</td></tr><tr class="miss"><td class="line">340</td><td class="hits">0</td><td class="source"> this.type(C('tpl_content_type'));</td></tr><tr><td class="line">341</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">342</td><td class="hits">0</td><td class="source"> return this.http.echo(obj, encoding);</td></tr><tr><td class="line">343</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">344</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">345</td><td class="hits"></td><td class="source"> * 结束输出,输出完成时一定要调用这个方法</td></tr><tr><td class="line">346</td><td class="hits"></td><td class="source"> * @param {[type]} obj [description]</td></tr><tr><td class="line">347</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">348</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">349</td><td class="hits"></td><td class="source"> end: function(obj, encoding) {</td></tr><tr class="miss"><td class="line">350</td><td class="hits">0</td><td class="source"> if (obj) {</td></tr><tr class="miss"><td class="line">351</td><td class="hits">0</td><td class="source"> this.echo(obj, encoding);</td></tr><tr><td class="line">352</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">353</td><td class="hits">0</td><td class="source"> this.http.end();</td></tr><tr><td class="line">354</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">355</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">356</td><td class="hits"></td><td class="source"> * 发送Content-Type</td></tr><tr><td class="line">357</td><td class="hits"></td><td class="source"> * @param {[type]} type [description]</td></tr><tr><td class="line">358</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">359</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">360</td><td class="hits"></td><td class="source"> type: function(ext){</td></tr><tr class="miss"><td class="line">361</td><td class="hits">0</td><td class="source"> if (ext.indexOf('/') === -1) {</td></tr><tr class="miss"><td class="line">362</td><td class="hits">0</td><td class="source"> ext = require('mime').lookup(ext);</td></tr><tr><td class="line">363</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">364</td><td class="hits">0</td><td class="source"> if (!this.http.cthIsSend) {</td></tr><tr class="miss"><td class="line">365</td><td class="hits">0</td><td class="source"> if (ext.toLowerCase().indexOf('charset=') === -1) {</td></tr><tr class="miss"><td class="line">366</td><td class="hits">0</td><td class="source"> ext += '; charset=' + C('encoding');</td></tr><tr><td class="line">367</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">368</td><td class="hits"></td><td class="source"> //Content-Type Header has been Send</td></tr><tr class="miss"><td class="line">369</td><td class="hits">0</td><td class="source"> this.http.cthIsSend = true;</td></tr><tr class="miss"><td class="line">370</td><td class="hits">0</td><td class="source"> this.http.setHeader('Content-Type', ext);</td></tr><tr><td class="line">371</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">372</td><td class="hits">0</td><td class="source"> console.log('Content-Type has been send');</td></tr><tr><td class="line">373</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">374</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">375</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">376</td><td class="hits"></td><td class="source"> * 下载文件</td></tr><tr><td class="line">377</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">378</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">379</td><td class="hits"></td><td class="source"> download: function(file, contentType, callback) {</td></tr><tr class="miss"><td class="line">380</td><td class="hits">0</td><td class="source"> if (isFunction(contentType)) {</td></tr><tr class="miss"><td class="line">381</td><td class="hits">0</td><td class="source"> callback = contentType;</td></tr><tr class="miss"><td class="line">382</td><td class="hits">0</td><td class="source"> contentType = '';</td></tr><tr><td class="line">383</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">384</td><td class="hits">0</td><td class="source"> if (!contentType || contentType.indexOf('/') === -1) {</td></tr><tr class="miss"><td class="line">385</td><td class="hits">0</td><td class="source"> contentType = require('mime').lookup(contentType || file);</td></tr><tr><td class="line">386</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">387</td><td class="hits">0</td><td class="source"> var http = this.http;</td></tr><tr class="miss"><td class="line">388</td><td class="hits">0</td><td class="source"> var fileStream = fs.createReadStream(file);</td></tr><tr class="miss"><td class="line">389</td><td class="hits">0</td><td class="source"> this.type(contentType);</td></tr><tr class="miss"><td class="line">390</td><td class="hits">0</td><td class="source"> http.setHeader('Content-Disposition', 'attachment; filename=&quot;' + path.basename(file) + '&quot;');</td></tr><tr class="miss"><td class="line">391</td><td class="hits">0</td><td class="source"> fileStream.pipe(http.res);</td></tr><tr class="miss"><td class="line">392</td><td class="hits">0</td><td class="source"> fileStream.on('end', function() {</td></tr><tr class="miss"><td class="line">393</td><td class="hits">0</td><td class="source"> http.end();</td></tr><tr class="miss"><td class="line">394</td><td class="hits">0</td><td class="source"> return callback &amp;&amp; callback();</td></tr><tr><td class="line">395</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">396</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">397</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">398</td><td class="hits"></td><td class="source"> * 正常json数据输出</td></tr><tr><td class="line">399</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">400</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">401</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">402</td><td class="hits"></td><td class="source"> success: function(data){</td></tr><tr class="miss"><td class="line">403</td><td class="hits">0</td><td class="source"> var obj = getObject([C('error_no_key'), C('error_msg_key')], [0, '']);</td></tr><tr class="miss"><td class="line">404</td><td class="hits">0</td><td class="source"> if (data !== undefined) {</td></tr><tr class="miss"><td class="line">405</td><td class="hits">0</td><td class="source"> obj.data = data;</td></tr><tr><td class="line">406</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">407</td><td class="hits">0</td><td class="source"> this.type(C('json_content_type'));</td></tr><tr class="miss"><td class="line">408</td><td class="hits">0</td><td class="source"> this.end(obj);</td></tr><tr class="miss"><td class="line">409</td><td class="hits">0</td><td class="source"> return getDefer().promise;</td></tr><tr><td class="line">410</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">411</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">412</td><td class="hits"></td><td class="source"> * 异常json数据数据</td></tr><tr><td class="line">413</td><td class="hits"></td><td class="source"> * @param {[type]} errno [description]</td></tr><tr><td class="line">414</td><td class="hits"></td><td class="source"> * @param {[type]} errmsg [description]</td></tr><tr><td class="line">415</td><td class="hits"></td><td class="source"> * @param {[type]} extra [description]</td></tr><tr><td class="line">416</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">417</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">418</td><td class="hits"></td><td class="source"> error: function(errno, errmsg, data){</td></tr><tr class="miss"><td class="line">419</td><td class="hits">0</td><td class="source"> var obj;</td></tr><tr class="miss"><td class="line">420</td><td class="hits">0</td><td class="source"> if (isObject(errno)) {</td></tr><tr class="miss"><td class="line">421</td><td class="hits">0</td><td class="source"> data = errmsg;</td></tr><tr class="miss"><td class="line">422</td><td class="hits">0</td><td class="source"> obj = extend({}, errno);</td></tr><tr><td class="line">423</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">424</td><td class="hits">0</td><td class="source"> if (!isNumber(errno)) {</td></tr><tr class="miss"><td class="line">425</td><td class="hits">0</td><td class="source"> data = errmsg;</td></tr><tr class="miss"><td class="line">426</td><td class="hits">0</td><td class="source"> errmsg = errno;</td></tr><tr class="miss"><td class="line">427</td><td class="hits">0</td><td class="source"> errno = C('error_no_default_value');</td></tr><tr><td class="line">428</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">429</td><td class="hits">0</td><td class="source"> obj = getObject([C('error_no_key'), C('error_msg_key')], [errno, errmsg]);</td></tr><tr><td class="line">430</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">431</td><td class="hits">0</td><td class="source"> if (data !== undefined) {</td></tr><tr class="miss"><td class="line">432</td><td class="hits">0</td><td class="source"> obj.data = data;</td></tr><tr><td class="line">433</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">434</td><td class="hits">0</td><td class="source"> this.type(C('json_content_type'));</td></tr><tr class="miss"><td class="line">435</td><td class="hits">0</td><td class="source"> this.end(obj);</td></tr><tr class="miss"><td class="line">436</td><td class="hits">0</td><td class="source"> return getDefer().promise;</td></tr><tr><td class="line">437</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">438</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">439</td><td class="hits"></td><td class="source"> * 发送执行时间</td></tr><tr><td class="line">440</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">441</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">442</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">443</td><td class="hits"></td><td class="source"> sendTime: function(name){</td></tr><tr class="miss"><td class="line">444</td><td class="hits">0</td><td class="source"> return this.http.sendTime(name);</td></tr><tr><td class="line">445</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">446</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">447</td><td class="hits"></td><td class="source"> * 对数据进行过滤</td></tr><tr><td class="line">448</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">449</td><td class="hits"></td><td class="source"> * @param {[type]} type [description]</td></tr><tr><td class="line">450</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">451</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">452</td><td class="hits"></td><td class="source"> filter: function() {</td></tr><tr class="miss"><td class="line">453</td><td class="hits">0</td><td class="source"> var filter = thinkRequire('Filter').filter;</td></tr><tr class="miss"><td class="line">454</td><td class="hits">0</td><td class="source"> return filter.apply(null, arguments);</td></tr><tr><td class="line">455</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">456</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">457</td><td class="hits"></td><td class="source"> * 校验一个值是否合法</td></tr><tr><td class="line">458</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">459</td><td class="hits"></td><td class="source"> * @param {[type]} validType [description]</td></tr><tr><td class="line">460</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">461</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">462</td><td class="hits"></td><td class="source"> valid: function(data, validType) {</td></tr><tr><td class="line">463</td><td class="hits"></td><td class="source"> //单个值检测,只返回是否正常</td></tr><tr class="miss"><td class="line">464</td><td class="hits">0</td><td class="source"> if (validType !== undefined) {</td></tr><tr class="miss"><td class="line">465</td><td class="hits">0</td><td class="source"> data = [{</td></tr><tr><td class="line">466</td><td class="hits"></td><td class="source"> value: data,</td></tr><tr><td class="line">467</td><td class="hits"></td><td class="source"> valid: validType</td></tr><tr><td class="line">468</td><td class="hits"></td><td class="source"> }];</td></tr><tr class="miss"><td class="line">469</td><td class="hits">0</td><td class="source"> var result = thinkRequire('Valid').check(data);</td></tr><tr class="miss"><td class="line">470</td><td class="hits">0</td><td class="source"> return result.length === 0;</td></tr><tr><td class="line">471</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">472</td><td class="hits">0</td><td class="source"> return thinkRequire('Valid').check(data);</td></tr><tr><td class="line">473</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">474</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">475</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Db.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Db.js</h2><div id="stats" class="terrible"><div class="percentage">2%</div><div class="sloc">346</div><div class="hits">10</div><div class="misses">336</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"><td class="line">1</td><td class="hits">1</td><td class="source">var url = require('url');</td></tr><tr class="hit"><td class="line">2</td><td class="hits">1</td><td class="source">var querystring = require('querystring');</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> * 数据库基类</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source">var Db = module.exports = Class(function(){</td></tr><tr class="hit"><td class="line">8</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> //用于查询的sql语句所有select语句根据该语句解析</td></tr><tr class="hit"><td class="line">10</td><td class="hits">1</td><td class="source"> var selectSql = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%COMMENT%';</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> //where条件里的表达式</td></tr><tr class="hit"><td class="line">12</td><td class="hits">1</td><td class="source"> var comparison = {</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> 'EQ': '=',</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> 'NEQ': '!=',</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> '&lt;&gt;': '!=',</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> 'GT': '&gt;',</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> 'EGT': '&gt;=',</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> 'LT': '&lt;',</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> 'ELT': '&lt;=',</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> 'NOTLIKE': 'NOT LIKE',</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> 'LIKE': 'LIKE',</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> 'IN': 'IN',</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> 'NOTIN': 'NOT IN'</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> };</td></tr><tr class="hit"><td class="line">25</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> // 数据库类型</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> dbType: null,</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> // 当前操作所属的模型名</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> model: '_think_',</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> // 当前SQL指令</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> queryStr: '',</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> // 操作的sql列表</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> modelSql: [],</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> // 数据库连接ID 支持多个连接</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> linkIds: [],</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> // 当前连接ID</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> linkId: null,</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> // 是否已经连接数据库</td></tr><tr><td class="line">39</td><td class="hits"></td><td class="source"> connected: false,</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> // 数据库连接参数配置</td></tr><tr><td class="line">41</td><td class="hits"></td><td class="source"> config: '',</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> * 初始化类似于constrcut类实例化时自动调用</td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">46</td><td class="hits"></td><td class="source"> init: function(){</td></tr><tr><td class="line">47</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">49</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> * 连接数据库</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> initConnect: function(){</td></tr><tr class="miss"><td class="line">54</td><td class="hits">0</td><td class="source"> if (!this.connected) {</td></tr><tr class="miss"><td class="line">55</td><td class="hits">0</td><td class="source"> this.linkId = this.connect();</td></tr><tr><td class="line">56</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">57</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">58</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">59</td><td class="hits"></td><td class="source"> * 解析set集合</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">62</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">63</td><td class="hits"></td><td class="source"> parseSet: function(data){</td></tr><tr class="miss"><td class="line">64</td><td class="hits">0</td><td class="source"> data = data || {};</td></tr><tr class="miss"><td class="line">65</td><td class="hits">0</td><td class="source"> var set = [];</td></tr><tr class="miss"><td class="line">66</td><td class="hits">0</td><td class="source"> for(var key in data){</td></tr><tr class="miss"><td class="line">67</td><td class="hits">0</td><td class="source"> var value = this.parseValue(data[key]);</td></tr><tr class="miss"><td class="line">68</td><td class="hits">0</td><td class="source"> if (isScalar(value)) {</td></tr><tr class="miss"><td class="line">69</td><td class="hits">0</td><td class="source"> set.push(this.parseKey(key) + '=' + value);</td></tr><tr><td class="line">70</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">71</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">72</td><td class="hits">0</td><td class="source"> return ' SET ' + set.join(',');</td></tr><tr><td class="line">73</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">74</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">75</td><td class="hits"></td><td class="source"> * 解析字段名,具体的数据库里实现</td></tr><tr><td class="line">76</td><td class="hits"></td><td class="source"> * @param {[type]} key [description]</td></tr><tr><td class="line">77</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">78</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">79</td><td class="hits"></td><td class="source"> parseKey: function(key){</td></tr><tr class="miss"><td class="line">80</td><td class="hits">0</td><td class="source"> return key;</td></tr><tr><td class="line">81</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">82</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> * value分析</td></tr><tr><td class="line">84</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">85</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">86</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">87</td><td class="hits"></td><td class="source"> parseValue: function(value){</td></tr><tr class="miss"><td class="line">88</td><td class="hits">0</td><td class="source"> if (isString(value)) {</td></tr><tr class="miss"><td class="line">89</td><td class="hits">0</td><td class="source"> value = '\'' + this.escapeString(value) + '\'';</td></tr><tr class="miss"><td class="line">90</td><td class="hits">0</td><td class="source"> }else if(isArray(value)){</td></tr><tr class="miss"><td class="line">91</td><td class="hits">0</td><td class="source"> if ((value[0] + '').toLowerCase() === 'exp') {</td></tr><tr class="miss"><td class="line">92</td><td class="hits">0</td><td class="source"> value = this.escapeString(value[1]);</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">94</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">95</td><td class="hits">0</td><td class="source"> value = value.map(function(item){</td></tr><tr class="miss"><td class="line">96</td><td class="hits">0</td><td class="source"> return self.parseValue(item);</td></tr><tr><td class="line">97</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">98</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">99</td><td class="hits">0</td><td class="source"> }else if(isBoolean(value)){</td></tr><tr class="miss"><td class="line">100</td><td class="hits">0</td><td class="source"> value = value ? '1' : '0';</td></tr><tr class="miss"><td class="line">101</td><td class="hits">0</td><td class="source"> }else if (value === null) {</td></tr><tr class="miss"><td class="line">102</td><td class="hits">0</td><td class="source"> value = 'null';</td></tr><tr><td class="line">103</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">104</td><td class="hits">0</td><td class="source"> return value;</td></tr><tr><td class="line">105</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">106</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">107</td><td class="hits"></td><td class="source"> * field分析</td></tr><tr><td class="line">108</td><td class="hits"></td><td class="source"> * parseField('name');</td></tr><tr><td class="line">109</td><td class="hits"></td><td class="source"> * parseField('name,email');</td></tr><tr><td class="line">110</td><td class="hits"></td><td class="source"> * parseField({</td></tr><tr><td class="line">111</td><td class="hits"></td><td class="source"> * xx_name: 'name',</td></tr><tr><td class="line">112</td><td class="hits"></td><td class="source"> * xx_email: 'email'</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source"> * })</td></tr><tr><td class="line">114</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">115</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">116</td><td class="hits"></td><td class="source"> parseField: function(fields){</td></tr><tr class="miss"><td class="line">117</td><td class="hits">0</td><td class="source"> if (isString(fields) &amp;&amp; fields.indexOf(',') &gt; -1) {</td></tr><tr class="miss"><td class="line">118</td><td class="hits">0</td><td class="source"> fields = fields.split(',');</td></tr><tr><td class="line">119</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">120</td><td class="hits">0</td><td class="source"> if (isArray(fields)) {</td></tr><tr class="miss"><td class="line">121</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">122</td><td class="hits">0</td><td class="source"> return fields.map(function(item){</td></tr><tr class="miss"><td class="line">123</td><td class="hits">0</td><td class="source"> return self.parseKey(item);</td></tr><tr><td class="line">124</td><td class="hits"></td><td class="source"> }).join(',');</td></tr><tr class="miss"><td class="line">125</td><td class="hits">0</td><td class="source"> }else if(isObject(fields)){</td></tr><tr class="miss"><td class="line">126</td><td class="hits">0</td><td class="source"> var data = [];</td></tr><tr class="miss"><td class="line">127</td><td class="hits">0</td><td class="source"> for(var key in fields){</td></tr><tr class="miss"><td class="line">128</td><td class="hits">0</td><td class="source"> data.push(this.parseKey(key) + ' AS ' + this.parseKey(fields[key]));</td></tr><tr><td class="line">129</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">130</td><td class="hits">0</td><td class="source"> return data.join(',');</td></tr><tr class="miss"><td class="line">131</td><td class="hits">0</td><td class="source"> }else if(isString(fields) &amp;&amp; fields){</td></tr><tr class="miss"><td class="line">132</td><td class="hits">0</td><td class="source"> return this.parseKey(fields);</td></tr><tr><td class="line">133</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">134</td><td class="hits">0</td><td class="source"> return '*';</td></tr><tr><td class="line">135</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">136</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">137</td><td class="hits"></td><td class="source"> * table别名分析</td></tr><tr><td class="line">138</td><td class="hits"></td><td class="source"> * @param {[type]} tables [description]</td></tr><tr><td class="line">139</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">140</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">141</td><td class="hits"></td><td class="source"> parseTable: function(tables){</td></tr><tr class="miss"><td class="line">142</td><td class="hits">0</td><td class="source"> if (isString(tables)) {</td></tr><tr class="miss"><td class="line">143</td><td class="hits">0</td><td class="source"> tables = tables.split(',');</td></tr><tr><td class="line">144</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">145</td><td class="hits">0</td><td class="source"> if (isArray(tables)) {</td></tr><tr class="miss"><td class="line">146</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">147</td><td class="hits">0</td><td class="source"> return tables.map(function(item){</td></tr><tr class="miss"><td class="line">148</td><td class="hits">0</td><td class="source"> return self.parseKey(item);</td></tr><tr><td class="line">149</td><td class="hits"></td><td class="source"> }).join(',');</td></tr><tr class="miss"><td class="line">150</td><td class="hits">0</td><td class="source"> }else if (isObject(tables)) {</td></tr><tr class="miss"><td class="line">151</td><td class="hits">0</td><td class="source"> var data = [];</td></tr><tr class="miss"><td class="line">152</td><td class="hits">0</td><td class="source"> for(var key in tables){</td></tr><tr class="miss"><td class="line">153</td><td class="hits">0</td><td class="source"> data.push(this.parseKey(key) + ' AS ' + this.parseKey(tables[key]));</td></tr><tr><td class="line">154</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">155</td><td class="hits">0</td><td class="source"> return data.join(',');</td></tr><tr><td class="line">156</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">157</td><td class="hits">0</td><td class="source"> return '';</td></tr><tr><td class="line">158</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">159</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">160</td><td class="hits"></td><td class="source"> * where条件分析</td></tr><tr><td class="line">161</td><td class="hits"></td><td class="source"> * @param {[type]} where [description]</td></tr><tr><td class="line">162</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">163</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">164</td><td class="hits"></td><td class="source"> parseWhere: function(where){</td></tr><tr class="miss"><td class="line">165</td><td class="hits">0</td><td class="source"> var whereStr = '';</td></tr><tr class="miss"><td class="line">166</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">167</td><td class="hits">0</td><td class="source"> where = where || {};</td></tr><tr class="miss"><td class="line">168</td><td class="hits">0</td><td class="source"> if (isString(where)) {</td></tr><tr class="miss"><td class="line">169</td><td class="hits">0</td><td class="source"> whereStr = where;</td></tr><tr><td class="line">170</td><td class="hits"></td><td class="source"> }else{</td></tr><tr><td class="line">171</td><td class="hits"></td><td class="source"> // 定义逻辑运算规则 例如 OR XOR AND NOT</td></tr><tr class="miss"><td class="line">172</td><td class="hits">0</td><td class="source"> var oList = ['AND', 'OR', 'XOR'];</td></tr><tr class="miss"><td class="line">173</td><td class="hits">0</td><td class="source"> var operate = (where._logic + '').toUpperCase();</td></tr><tr class="miss"><td class="line">174</td><td class="hits">0</td><td class="source"> delete where._logic;</td></tr><tr class="miss"><td class="line">175</td><td class="hits">0</td><td class="source"> operate = oList.indexOf(operate) &gt; -1 ? ' ' + operate + ' ' : ' AND ';</td></tr><tr><td class="line">176</td><td class="hits"></td><td class="source"> //key值的安全检测正则</td></tr><tr class="miss"><td class="line">177</td><td class="hits">0</td><td class="source"> var keySafeRegExp = /^[\w\|\&amp;\-\.\(\)\,]+$/;</td></tr><tr class="miss"><td class="line">178</td><td class="hits">0</td><td class="source"> var multi = where._multi;</td></tr><tr class="miss"><td class="line">179</td><td class="hits">0</td><td class="source"> delete where._multi;</td></tr><tr><td class="line">180</td><td class="hits"></td><td class="source"> </td></tr><tr class="miss"><td class="line">181</td><td class="hits">0</td><td class="source"> var val;</td></tr><tr class="miss"><td class="line">182</td><td class="hits">0</td><td class="source"> var fn = function(item, i){</td></tr><tr class="miss"><td class="line">183</td><td class="hits">0</td><td class="source"> var v = multi ? val[i] : val;</td></tr><tr class="miss"><td class="line">184</td><td class="hits">0</td><td class="source"> return '(' + self.parseWhereItem(self.parseKey(item), v) + ')';</td></tr><tr><td class="line">185</td><td class="hits"></td><td class="source"> };</td></tr><tr class="miss"><td class="line">186</td><td class="hits">0</td><td class="source"> for(var key in where){</td></tr><tr class="miss"><td class="line">187</td><td class="hits">0</td><td class="source"> key = key.trim();</td></tr><tr class="miss"><td class="line">188</td><td class="hits">0</td><td class="source"> val = where[key];</td></tr><tr class="miss"><td class="line">189</td><td class="hits">0</td><td class="source"> whereStr += '( ';</td></tr><tr class="miss"><td class="line">190</td><td class="hits">0</td><td class="source"> if (key.indexOf('_') === 0) {</td></tr><tr><td class="line">191</td><td class="hits"></td><td class="source"> // 解析特殊条件表达式</td></tr><tr class="miss"><td class="line">192</td><td class="hits">0</td><td class="source"> whereStr += this.parseThinkWhere(key, val);</td></tr><tr><td class="line">193</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">194</td><td class="hits">0</td><td class="source"> if (!keySafeRegExp.test(key)) {</td></tr><tr class="miss"><td class="line">195</td><td class="hits">0</td><td class="source"> console.log(key + ' is not safe');</td></tr><tr class="miss"><td class="line">196</td><td class="hits">0</td><td class="source"> continue;</td></tr><tr><td class="line">197</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">198</td><td class="hits">0</td><td class="source"> var arr;</td></tr><tr><td class="line">199</td><td class="hits"></td><td class="source"> // 支持 name|title|nickname 方式定义查询字段</td></tr><tr class="miss"><td class="line">200</td><td class="hits">0</td><td class="source"> if (key.indexOf('|') &gt; -1) {</td></tr><tr class="miss"><td class="line">201</td><td class="hits">0</td><td class="source"> arr = key.split('|');</td></tr><tr class="miss"><td class="line">202</td><td class="hits">0</td><td class="source"> whereStr += arr.map(fn).join(' OR ');</td></tr><tr class="miss"><td class="line">203</td><td class="hits">0</td><td class="source"> }else if (key.indexOf('&amp;') &gt; -1) {</td></tr><tr class="miss"><td class="line">204</td><td class="hits">0</td><td class="source"> arr = key.split('&amp;');</td></tr><tr class="miss"><td class="line">205</td><td class="hits">0</td><td class="source"> whereStr += arr.map(fn).join(' AND ');</td></tr><tr><td class="line">206</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">207</td><td class="hits">0</td><td class="source"> whereStr += this.parseWhereItem(this.parseKey(key), val);</td></tr><tr><td class="line">208</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">209</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">210</td><td class="hits">0</td><td class="source"> whereStr += ' )' + operate;</td></tr><tr><td class="line">211</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">212</td><td class="hits">0</td><td class="source"> whereStr = whereStr.substr(0, whereStr.length - operate.length);</td></tr><tr><td class="line">213</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">214</td><td class="hits"></td><td class="source"> </td></tr><tr class="miss"><td class="line">215</td><td class="hits">0</td><td class="source"> return whereStr ? (' WHERE ' + whereStr) : '';</td></tr><tr><td class="line">216</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">217</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">218</td><td class="hits"></td><td class="source"> * 解析单个查询条件</td></tr><tr><td class="line">219</td><td class="hits"></td><td class="source"> * @param {[type]} key [description]</td></tr><tr><td class="line">220</td><td class="hits"></td><td class="source"> * @param {[type]} val [description]</td></tr><tr><td class="line">221</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">222</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">223</td><td class="hits"></td><td class="source"> parseWhereItem: function(key, val){</td></tr><tr class="miss"><td class="line">224</td><td class="hits">0</td><td class="source"> if (!isArray(val)) {</td></tr><tr><td class="line">225</td><td class="hits"></td><td class="source"> //对字符串类型字段采用模糊匹配</td></tr><tr class="miss"><td class="line">226</td><td class="hits">0</td><td class="source"> if (C('db_like_fields').indexOf(key) &gt; -1) {</td></tr><tr class="miss"><td class="line">227</td><td class="hits">0</td><td class="source"> return key + ' LIKE ' + this.parseValue('%' + val + '%');</td></tr><tr><td class="line">228</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">229</td><td class="hits">0</td><td class="source"> return key + ' = ' + this.parseValue(val);</td></tr><tr><td class="line">230</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">231</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">232</td><td class="hits">0</td><td class="source"> var whereStr = '';</td></tr><tr class="miss"><td class="line">233</td><td class="hits">0</td><td class="source"> var data;</td></tr><tr class="miss"><td class="line">234</td><td class="hits">0</td><td class="source"> if (isString(val[0])) {</td></tr><tr class="miss"><td class="line">235</td><td class="hits">0</td><td class="source"> var val0 = val[0].toUpperCase();</td></tr><tr class="miss"><td class="line">236</td><td class="hits">0</td><td class="source"> val0 = comparison[val0] || val0;</td></tr><tr class="miss"><td class="line">237</td><td class="hits">0</td><td class="source"> if (/^(=|!=|&gt;|&gt;=|&lt;|&lt;=)$/.test(val0)) { // 比较运算</td></tr><tr class="miss"><td class="line">238</td><td class="hits">0</td><td class="source"> whereStr += key + ' ' + val0 + ' ' + this.parseValue(val[1]);</td></tr><tr class="miss"><td class="line">239</td><td class="hits">0</td><td class="source"> }else if (/^(NOT\s+LIKE|LIKE)$/.test(val0)) { // 模糊查找</td></tr><tr class="miss"><td class="line">240</td><td class="hits">0</td><td class="source"> if (isArray(val[1])) {</td></tr><tr class="miss"><td class="line">241</td><td class="hits">0</td><td class="source"> var likeLogic = (val[2] ? val[2] : 'OR').toUpperCase();</td></tr><tr class="miss"><td class="line">242</td><td class="hits">0</td><td class="source"> var likesLogic = ['AND','OR','XOR'];</td></tr><tr class="miss"><td class="line">243</td><td class="hits">0</td><td class="source"> if (likesLogic.indexOf(likeLogic) &gt; -1) {</td></tr><tr class="miss"><td class="line">244</td><td class="hits">0</td><td class="source"> var like = val[1].map(function(item){</td></tr><tr class="miss"><td class="line">245</td><td class="hits">0</td><td class="source"> return key + ' ' + val0 + ' ' + this.parseValue(item);</td></tr><tr><td class="line">246</td><td class="hits"></td><td class="source"> }).join(likeLogic);</td></tr><tr class="miss"><td class="line">247</td><td class="hits">0</td><td class="source"> whereStr += '(' + like + ')';</td></tr><tr><td class="line">248</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">249</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">250</td><td class="hits">0</td><td class="source"> whereStr += key + ' ' + val0 + ' ' + this.parseValue(val[1]);</td></tr><tr><td class="line">251</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">252</td><td class="hits">0</td><td class="source"> }else if(val0 === 'EXP'){ // 使用表达式</td></tr><tr class="miss"><td class="line">253</td><td class="hits">0</td><td class="source"> whereStr += '(' + key + ' ' + val[1] + ')';</td></tr><tr class="miss"><td class="line">254</td><td class="hits">0</td><td class="source"> }else if(val0 === 'IN' || val0 === 'NOT IN'){ // IN 运算</td></tr><tr class="miss"><td class="line">255</td><td class="hits">0</td><td class="source"> if (val[2] === 'exp') {</td></tr><tr class="miss"><td class="line">256</td><td class="hits">0</td><td class="source"> whereStr += key + ' ' + val0 + ' ' + val[1];</td></tr><tr><td class="line">257</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">258</td><td class="hits">0</td><td class="source"> if (isString(val[1])) {</td></tr><tr class="miss"><td class="line">259</td><td class="hits">0</td><td class="source"> val[1] = val[1].split(',');</td></tr><tr><td class="line">260</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">261</td><td class="hits">0</td><td class="source"> val[1] = this.parseValue(val[1]);</td></tr><tr><td class="line">262</td><td class="hits"></td><td class="source"> //如果只有一个值,那么变成=或者!=</td></tr><tr class="miss"><td class="line">263</td><td class="hits">0</td><td class="source"> if (val[1].length === 1) {</td></tr><tr class="miss"><td class="line">264</td><td class="hits">0</td><td class="source"> whereStr += key + (val0 === 'IN' ? ' = ' : ' != ') + val[1];</td></tr><tr><td class="line">265</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">266</td><td class="hits">0</td><td class="source"> whereStr += key + ' ' + val0 + ' (' + val[1].join(',') + ')';</td></tr><tr><td class="line">267</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">268</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">269</td><td class="hits">0</td><td class="source"> }else if(val0 === 'BETWEEN'){ // BETWEEN运算</td></tr><tr class="miss"><td class="line">270</td><td class="hits">0</td><td class="source"> data = isString(val[1]) ? val[1].split(',') : val[1];</td></tr><tr class="miss"><td class="line">271</td><td class="hits">0</td><td class="source"> if (!isArray(data)) {</td></tr><tr class="miss"><td class="line">272</td><td class="hits">0</td><td class="source"> data = [val[1], val[2]];</td></tr><tr><td class="line">273</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">274</td><td class="hits">0</td><td class="source"> whereStr += ' (' + key + ' ' + val0 + ' ' + this.parseValue(data[0]);</td></tr><tr class="miss"><td class="line">275</td><td class="hits">0</td><td class="source"> whereStr += ' AND ' + this.parseValue(data[1]) + ')';</td></tr><tr><td class="line">276</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">277</td><td class="hits">0</td><td class="source"> console.log('_EXPRESS_ERROR_', key, val);</td></tr><tr class="miss"><td class="line">278</td><td class="hits">0</td><td class="source"> return '';</td></tr><tr><td class="line">279</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">280</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">281</td><td class="hits">0</td><td class="source"> var length = val.length;</td></tr><tr class="miss"><td class="line">282</td><td class="hits">0</td><td class="source"> var rule = val[val.length - 1] || '';</td></tr><tr class="miss"><td class="line">283</td><td class="hits">0</td><td class="source"> if (rule &amp;&amp; ['AND','OR','XOR'].indexOf(rule) &gt; -1) {</td></tr><tr class="miss"><td class="line">284</td><td class="hits">0</td><td class="source"> length = length - 1;</td></tr><tr><td class="line">285</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">286</td><td class="hits">0</td><td class="source"> rule = 'AND';</td></tr><tr><td class="line">287</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">288</td><td class="hits">0</td><td class="source"> for(var i = 0; i &lt; length; i++){</td></tr><tr class="miss"><td class="line">289</td><td class="hits">0</td><td class="source"> data = isArray(val[i]) ? val[i][1] : val[i];</td></tr><tr class="miss"><td class="line">290</td><td class="hits">0</td><td class="source"> var exp = ((isArray(val[i]) &amp;&amp; val[i][0]) + '').toLowerCase();</td></tr><tr class="miss"><td class="line">291</td><td class="hits">0</td><td class="source"> if (exp === 'exp') {</td></tr><tr class="miss"><td class="line">292</td><td class="hits">0</td><td class="source"> whereStr += '(' + key + ' ' + data + ') ' + rule + ' ';</td></tr><tr><td class="line">293</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">294</td><td class="hits">0</td><td class="source"> var op = isArray(val[i]) ? comparison[val[i][0].toUpperCase()] : '=';</td></tr><tr class="miss"><td class="line">295</td><td class="hits">0</td><td class="source"> whereStr += '(' + key + ' ' + op + ' ' + this.parseValue(data) + ') ' + rule + ' ';</td></tr><tr><td class="line">296</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">297</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">298</td><td class="hits">0</td><td class="source"> whereStr = whereStr.substr(0, whereStr.length - 4);</td></tr><tr><td class="line">299</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">300</td><td class="hits">0</td><td class="source"> return whereStr;</td></tr><tr><td class="line">301</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">302</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">303</td><td class="hits"></td><td class="source"> * 解析一些特殊的where条件</td></tr><tr><td class="line">304</td><td class="hits"></td><td class="source"> * @param {[type]} key [description]</td></tr><tr><td class="line">305</td><td class="hits"></td><td class="source"> * @param {[type]} val [description]</td></tr><tr><td class="line">306</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">307</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">308</td><td class="hits"></td><td class="source"> parseThinkWhere: function(key, val){</td></tr><tr class="miss"><td class="line">309</td><td class="hits">0</td><td class="source"> switch(key){</td></tr><tr><td class="line">310</td><td class="hits"></td><td class="source"> // 字符串模式查询条件</td></tr><tr><td class="line">311</td><td class="hits"></td><td class="source"> case '_string':</td></tr><tr class="miss"><td class="line">312</td><td class="hits">0</td><td class="source"> return val;</td></tr><tr><td class="line">313</td><td class="hits"></td><td class="source"> // 复合查询条件</td></tr><tr><td class="line">314</td><td class="hits"></td><td class="source"> case '_complex':</td></tr><tr class="miss"><td class="line">315</td><td class="hits">0</td><td class="source"> return this.parseWhere(val).substr(6);</td></tr><tr><td class="line">316</td><td class="hits"></td><td class="source"> // 字符串模式查询条件</td></tr><tr><td class="line">317</td><td class="hits"></td><td class="source"> case '_query':</td></tr><tr class="miss"><td class="line">318</td><td class="hits">0</td><td class="source"> var where = querystring.parse(val);</td></tr><tr class="miss"><td class="line">319</td><td class="hits">0</td><td class="source"> var op = ' AND ';</td></tr><tr class="miss"><td class="line">320</td><td class="hits">0</td><td class="source"> if ('_logic' in where) {</td></tr><tr class="miss"><td class="line">321</td><td class="hits">0</td><td class="source"> op = ' ' + where._logic.toLowerCase() + ' ';</td></tr><tr class="miss"><td class="line">322</td><td class="hits">0</td><td class="source"> delete where._logic;</td></tr><tr><td class="line">323</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">324</td><td class="hits">0</td><td class="source"> var arr = [];</td></tr><tr class="miss"><td class="line">325</td><td class="hits">0</td><td class="source"> for(var name in where){</td></tr><tr class="miss"><td class="line">326</td><td class="hits">0</td><td class="source"> val = where[name];</td></tr><tr class="miss"><td class="line">327</td><td class="hits">0</td><td class="source"> val = this.parseKey(name) + ' = ' + this.parseValue(val);</td></tr><tr class="miss"><td class="line">328</td><td class="hits">0</td><td class="source"> arr.push(val);</td></tr><tr><td class="line">329</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">330</td><td class="hits">0</td><td class="source"> return arr.join(op);</td></tr><tr><td class="line">331</td><td class="hits"></td><td class="source"> default:</td></tr><tr class="miss"><td class="line">332</td><td class="hits">0</td><td class="source"> return '';</td></tr><tr><td class="line">333</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">334</td><td class="hits">0</td><td class="source"> return '';</td></tr><tr><td class="line">335</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">336</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">337</td><td class="hits"></td><td class="source"> * 解析limit对非法的limit进行过滤</td></tr><tr><td class="line">338</td><td class="hits"></td><td class="source"> * @param {[type]} limit [description]</td></tr><tr><td class="line">339</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">340</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">341</td><td class="hits"></td><td class="source"> parseLimit: function(limit){</td></tr><tr class="miss"><td class="line">342</td><td class="hits">0</td><td class="source"> limit = (limit + '').split(',').slice(0, 2);</td></tr><tr class="miss"><td class="line">343</td><td class="hits">0</td><td class="source"> var flag = limit.every(function(item){</td></tr><tr class="miss"><td class="line">344</td><td class="hits">0</td><td class="source"> return isNumberString(item);</td></tr><tr><td class="line">345</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">346</td><td class="hits">0</td><td class="source"> if (!flag) {</td></tr><tr class="miss"><td class="line">347</td><td class="hits">0</td><td class="source"> return '';</td></tr><tr><td class="line">348</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">349</td><td class="hits">0</td><td class="source"> limit = limit.join(',');</td></tr><tr class="miss"><td class="line">350</td><td class="hits">0</td><td class="source"> return limit ? (' LIMIT ' + limit) : '';</td></tr><tr><td class="line">351</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">352</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">353</td><td class="hits"></td><td class="source"> * 解析join</td></tr><tr><td class="line">354</td><td class="hits"></td><td class="source"> * @param {[type]} join [description]</td></tr><tr><td class="line">355</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">356</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">357</td><td class="hits"></td><td class="source"> parseJoin: function(join){</td></tr><tr class="miss"><td class="line">358</td><td class="hits">0</td><td class="source"> var joinStr = '';</td></tr><tr class="miss"><td class="line">359</td><td class="hits">0</td><td class="source"> if (!join) {</td></tr><tr class="miss"><td class="line">360</td><td class="hits">0</td><td class="source"> return '';</td></tr><tr><td class="line">361</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">362</td><td class="hits">0</td><td class="source"> if (isArray(join)) {</td></tr><tr class="miss"><td class="line">363</td><td class="hits">0</td><td class="source"> join.forEach(function(val){</td></tr><tr class="miss"><td class="line">364</td><td class="hits">0</td><td class="source"> if (val.toLowerCase().indexOf('join') &gt; -1) {</td></tr><tr class="miss"><td class="line">365</td><td class="hits">0</td><td class="source"> joinStr += val;</td></tr><tr><td class="line">366</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">367</td><td class="hits">0</td><td class="source"> joinStr += ' LEFT JOIN ' + val;</td></tr><tr><td class="line">368</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">369</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">370</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">371</td><td class="hits">0</td><td class="source"> joinStr += ' LEFT JOIN ' + join;</td></tr><tr><td class="line">372</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">373</td><td class="hits">0</td><td class="source"> return joinStr;</td></tr><tr><td class="line">374</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">375</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">376</td><td class="hits"></td><td class="source"> * 解析order</td></tr><tr><td class="line">377</td><td class="hits"></td><td class="source"> * @param {[type]} order [description]</td></tr><tr><td class="line">378</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">379</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">380</td><td class="hits"></td><td class="source"> parseOrder: function(order){</td></tr><tr class="miss"><td class="line">381</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">382</td><td class="hits">0</td><td class="source"> if (isArray(order)) {</td></tr><tr class="miss"><td class="line">383</td><td class="hits">0</td><td class="source"> order = order.map(function(item){</td></tr><tr class="miss"><td class="line">384</td><td class="hits">0</td><td class="source"> return self.parseKey(item);</td></tr><tr><td class="line">385</td><td class="hits"></td><td class="source"> }).join(',');</td></tr><tr class="miss"><td class="line">386</td><td class="hits">0</td><td class="source"> }else if (isObject(order)) {</td></tr><tr class="miss"><td class="line">387</td><td class="hits">0</td><td class="source"> var arr = [];</td></tr><tr class="miss"><td class="line">388</td><td class="hits">0</td><td class="source"> for(var key in order){</td></tr><tr class="miss"><td class="line">389</td><td class="hits">0</td><td class="source"> var val = order[key];</td></tr><tr class="miss"><td class="line">390</td><td class="hits">0</td><td class="source"> val = this.parseKey(key) + ' ' + val;</td></tr><tr class="miss"><td class="line">391</td><td class="hits">0</td><td class="source"> arr.push(val);</td></tr><tr><td class="line">392</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">393</td><td class="hits">0</td><td class="source"> order = arr.join(',');</td></tr><tr><td class="line">394</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">395</td><td class="hits">0</td><td class="source"> return order ? (' ORDER BY ' + order) : '';</td></tr><tr><td class="line">396</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">397</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">398</td><td class="hits"></td><td class="source"> * 解析group</td></tr><tr><td class="line">399</td><td class="hits"></td><td class="source"> * @param {[type]} group [description]</td></tr><tr><td class="line">400</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">401</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">402</td><td class="hits"></td><td class="source"> parseGroup: function(group){</td></tr><tr class="miss"><td class="line">403</td><td class="hits">0</td><td class="source"> return group ? (' GROUP BY ' + group) : '';</td></tr><tr><td class="line">404</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">405</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">406</td><td class="hits"></td><td class="source"> * 解析having</td></tr><tr><td class="line">407</td><td class="hits"></td><td class="source"> * @param {[type]} having [description]</td></tr><tr><td class="line">408</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">409</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">410</td><td class="hits"></td><td class="source"> parseHaving: function(having){</td></tr><tr class="miss"><td class="line">411</td><td class="hits">0</td><td class="source"> return having ? (' HAVING ' + having) : '';</td></tr><tr><td class="line">412</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">413</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">414</td><td class="hits"></td><td class="source"> * 解析注释,一般情况下用不到</td></tr><tr><td class="line">415</td><td class="hits"></td><td class="source"> * @param {[type]} comment [description]</td></tr><tr><td class="line">416</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">417</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">418</td><td class="hits"></td><td class="source"> parseComment: function(comment){</td></tr><tr class="miss"><td class="line">419</td><td class="hits">0</td><td class="source"> return comment ? (' /* ' + comment + '*/') : ''; </td></tr><tr><td class="line">420</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">421</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">422</td><td class="hits"></td><td class="source"> * 解析Distinct</td></tr><tr><td class="line">423</td><td class="hits"></td><td class="source"> * @param {[type]} distinct [description]</td></tr><tr><td class="line">424</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">425</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">426</td><td class="hits"></td><td class="source"> parseDistinct: function(distinct){</td></tr><tr class="miss"><td class="line">427</td><td class="hits">0</td><td class="source"> return distinct ? ' Distinct ' : '';</td></tr><tr><td class="line">428</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">429</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">430</td><td class="hits"></td><td class="source"> * 解析Union</td></tr><tr><td class="line">431</td><td class="hits"></td><td class="source"> * @param {[type]} union [description]</td></tr><tr><td class="line">432</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">433</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">434</td><td class="hits"></td><td class="source"> parseUnion: function(union){</td></tr><tr class="miss"><td class="line">435</td><td class="hits">0</td><td class="source"> if (!union) {</td></tr><tr class="miss"><td class="line">436</td><td class="hits">0</td><td class="source"> return '';</td></tr><tr><td class="line">437</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">438</td><td class="hits">0</td><td class="source"> var str = '';</td></tr><tr class="miss"><td class="line">439</td><td class="hits">0</td><td class="source"> if ('_all' in union) {</td></tr><tr class="miss"><td class="line">440</td><td class="hits">0</td><td class="source"> str = 'UNION ALL ';</td></tr><tr class="miss"><td class="line">441</td><td class="hits">0</td><td class="source"> delete union._all;</td></tr><tr><td class="line">442</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">443</td><td class="hits">0</td><td class="source"> str = 'UNION ';</td></tr><tr><td class="line">444</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">445</td><td class="hits">0</td><td class="source"> var sql = [];</td></tr><tr class="miss"><td class="line">446</td><td class="hits">0</td><td class="source"> for(var key in union){</td></tr><tr class="miss"><td class="line">447</td><td class="hits">0</td><td class="source"> var val = union[key];</td></tr><tr class="miss"><td class="line">448</td><td class="hits">0</td><td class="source"> val = str + (isArray(val) ? this.buildSelectSql(val) : val);</td></tr><tr class="miss"><td class="line">449</td><td class="hits">0</td><td class="source"> sql.push(sql);</td></tr><tr><td class="line">450</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">451</td><td class="hits">0</td><td class="source"> return sql.join(' ');</td></tr><tr><td class="line">452</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">453</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">454</td><td class="hits"></td><td class="source"> * 解析Lock</td></tr><tr><td class="line">455</td><td class="hits"></td><td class="source"> * @param {[type]} lock [description]</td></tr><tr><td class="line">456</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">457</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">458</td><td class="hits"></td><td class="source"> parseLock: function(lock){</td></tr><tr class="miss"><td class="line">459</td><td class="hits">0</td><td class="source"> if (!lock) {</td></tr><tr class="miss"><td class="line">460</td><td class="hits">0</td><td class="source"> return '';</td></tr><tr><td class="line">461</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">462</td><td class="hits">0</td><td class="source"> return ' FOR UPDATE ';</td></tr><tr><td class="line">463</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">464</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">465</td><td class="hits"></td><td class="source"> * 将page转化为sql里的limit</td></tr><tr><td class="line">466</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">467</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">468</td><td class="hits"></td><td class="source"> pageToLimit: function(options){</td></tr><tr class="miss"><td class="line">469</td><td class="hits">0</td><td class="source"> options = options || {};</td></tr><tr><td class="line">470</td><td class="hits"></td><td class="source"> //根据page生成limit</td></tr><tr class="miss"><td class="line">471</td><td class="hits">0</td><td class="source"> if ('page' in options) {</td></tr><tr class="miss"><td class="line">472</td><td class="hits">0</td><td class="source"> var page = options.page + '';</td></tr><tr class="miss"><td class="line">473</td><td class="hits">0</td><td class="source"> var listRows = 0;</td></tr><tr class="miss"><td class="line">474</td><td class="hits">0</td><td class="source"> if (page.indexOf(',') &gt; -1) {</td></tr><tr class="miss"><td class="line">475</td><td class="hits">0</td><td class="source"> page = page.split(',');</td></tr><tr class="miss"><td class="line">476</td><td class="hits">0</td><td class="source"> listRows = page[1];</td></tr><tr class="miss"><td class="line">477</td><td class="hits">0</td><td class="source"> page = page[0];</td></tr><tr><td class="line">478</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">479</td><td class="hits">0</td><td class="source"> page = parseInt(page, 10) || 1;</td></tr><tr class="miss"><td class="line">480</td><td class="hits">0</td><td class="source"> if (!listRows) {</td></tr><tr class="miss"><td class="line">481</td><td class="hits">0</td><td class="source"> listRows = isNumberString(options.limit) ? options.limit : C('db_nums_per_page');</td></tr><tr><td class="line">482</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">483</td><td class="hits">0</td><td class="source"> var offset = listRows * (page - 1);</td></tr><tr class="miss"><td class="line">484</td><td class="hits">0</td><td class="source"> options.limit = offset + ',' + listRows;</td></tr><tr><td class="line">485</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">486</td><td class="hits">0</td><td class="source"> return options;</td></tr><tr><td class="line">487</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">488</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">489</td><td class="hits"></td><td class="source"> * 拼接select查询语句</td></tr><tr><td class="line">490</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">491</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">492</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">493</td><td class="hits"></td><td class="source"> buildSelectSql: function(options){</td></tr><tr class="miss"><td class="line">494</td><td class="hits">0</td><td class="source"> options = this.pageToLimit(options);</td></tr><tr class="miss"><td class="line">495</td><td class="hits">0</td><td class="source"> var sql = this.parseSql(selectSql, options);</td></tr><tr class="miss"><td class="line">496</td><td class="hits">0</td><td class="source"> sql += this.parseLock(options.lock);</td></tr><tr class="miss"><td class="line">497</td><td class="hits">0</td><td class="source"> return sql;</td></tr><tr><td class="line">498</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">499</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">500</td><td class="hits"></td><td class="source"> * 解析sql语句</td></tr><tr><td class="line">501</td><td class="hits"></td><td class="source"> * @param {[type]} sql [description]</td></tr><tr><td class="line">502</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">503</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">504</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">505</td><td class="hits"></td><td class="source"> parseSql: function(sql, options){</td></tr><tr class="miss"><td class="line">506</td><td class="hits">0</td><td class="source"> options = options || {};</td></tr><tr class="miss"><td class="line">507</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">508</td><td class="hits">0</td><td class="source"> return sql.replace(/\%([A-Z]+)\%/g, function(a, type){</td></tr><tr class="miss"><td class="line">509</td><td class="hits">0</td><td class="source"> type = type.toLowerCase();</td></tr><tr class="miss"><td class="line">510</td><td class="hits">0</td><td class="source"> return self['parse' + ucfirst(type)](options[type] || '');</td></tr><tr><td class="line">511</td><td class="hits"></td><td class="source"> }).replace(/__([A-Z_-]+)__/g, function(a, b){</td></tr><tr class="miss"><td class="line">512</td><td class="hits">0</td><td class="source"> return '`' + C('db_prefix') + b.toLowerCase() + '`';</td></tr><tr><td class="line">513</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">514</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">515</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">516</td><td class="hits"></td><td class="source"> * 插入一条记录</td></tr><tr><td class="line">517</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">518</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">519</td><td class="hits"></td><td class="source"> * @param {[type]} replace [description]</td></tr><tr><td class="line">520</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">521</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">522</td><td class="hits"></td><td class="source"> insert: function(data, options, replace){</td></tr><tr class="miss"><td class="line">523</td><td class="hits">0</td><td class="source"> data = data || {};</td></tr><tr class="miss"><td class="line">524</td><td class="hits">0</td><td class="source"> options = options || {};</td></tr><tr class="miss"><td class="line">525</td><td class="hits">0</td><td class="source"> var values = [];</td></tr><tr class="miss"><td class="line">526</td><td class="hits">0</td><td class="source"> var fields = [];</td></tr><tr class="miss"><td class="line">527</td><td class="hits">0</td><td class="source"> this.model = options.model;</td></tr><tr class="miss"><td class="line">528</td><td class="hits">0</td><td class="source"> for(var key in data){</td></tr><tr class="miss"><td class="line">529</td><td class="hits">0</td><td class="source"> var val = data[key];</td></tr><tr class="miss"><td class="line">530</td><td class="hits">0</td><td class="source"> val = this.parseValue(val);</td></tr><tr class="miss"><td class="line">531</td><td class="hits">0</td><td class="source"> if (isScalar(val)) {</td></tr><tr class="miss"><td class="line">532</td><td class="hits">0</td><td class="source"> values.push(val);</td></tr><tr class="miss"><td class="line">533</td><td class="hits">0</td><td class="source"> fields.push(this.parseKey(key));</td></tr><tr><td class="line">534</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">535</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">536</td><td class="hits">0</td><td class="source"> var sql = (replace ? 'REPLACE' : 'INSERT') + ' INTO ';</td></tr><tr class="miss"><td class="line">537</td><td class="hits">0</td><td class="source"> sql += this.parseTable(options.table) + ' (' + fields.join(',') + ') ';</td></tr><tr class="miss"><td class="line">538</td><td class="hits">0</td><td class="source"> sql += 'VALUES(' + values.join(',') + ')';</td></tr><tr class="miss"><td class="line">539</td><td class="hits">0</td><td class="source"> sql += this.parseLock(options.lock) + this.parseComment(options.comment);</td></tr><tr class="miss"><td class="line">540</td><td class="hits">0</td><td class="source"> return this.execute(sql);</td></tr><tr><td class="line">541</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">542</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">543</td><td class="hits"></td><td class="source"> * 插入多条记录</td></tr><tr><td class="line">544</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">545</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">546</td><td class="hits"></td><td class="source"> * @param {[type]} replace [description]</td></tr><tr><td class="line">547</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">548</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">549</td><td class="hits"></td><td class="source"> insertAll: function(data, options, replace){</td></tr><tr class="miss"><td class="line">550</td><td class="hits">0</td><td class="source"> var fields = Object.keys(data[0]);</td></tr><tr class="miss"><td class="line">551</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">552</td><td class="hits">0</td><td class="source"> fields = fields.map(function(item){</td></tr><tr class="miss"><td class="line">553</td><td class="hits">0</td><td class="source"> return self.parseKey(item);</td></tr><tr><td class="line">554</td><td class="hits"></td><td class="source"> }).join(',');</td></tr><tr class="miss"><td class="line">555</td><td class="hits">0</td><td class="source"> var values = data.map(function(item){</td></tr><tr class="miss"><td class="line">556</td><td class="hits">0</td><td class="source"> var value = [];</td></tr><tr class="miss"><td class="line">557</td><td class="hits">0</td><td class="source"> for(var key in item){</td></tr><tr class="miss"><td class="line">558</td><td class="hits">0</td><td class="source"> var val = item[key];</td></tr><tr class="miss"><td class="line">559</td><td class="hits">0</td><td class="source"> val = self.parseValue(val);</td></tr><tr class="miss"><td class="line">560</td><td class="hits">0</td><td class="source"> if (isScalar(val)) {</td></tr><tr class="miss"><td class="line">561</td><td class="hits">0</td><td class="source"> value.push(val);</td></tr><tr><td class="line">562</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">563</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">564</td><td class="hits">0</td><td class="source"> return '(' + value.join(',') + ')';</td></tr><tr><td class="line">565</td><td class="hits"></td><td class="source"> }).join(',');</td></tr><tr class="miss"><td class="line">566</td><td class="hits">0</td><td class="source"> var sql = replace ? 'REPLACE' : 'INSERT';</td></tr><tr class="miss"><td class="line">567</td><td class="hits">0</td><td class="source"> sql += ' INTO ' + this.parseTable(options.table) + '(' + fields + ') VALUES ' + values;</td></tr><tr class="miss"><td class="line">568</td><td class="hits">0</td><td class="source"> return this.execute(sql);</td></tr><tr><td class="line">569</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">570</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">571</td><td class="hits"></td><td class="source"> * 从一个选择条件的结果插入记录</td></tr><tr><td class="line">572</td><td class="hits"></td><td class="source"> * @param {[type]} fields [description]</td></tr><tr><td class="line">573</td><td class="hits"></td><td class="source"> * @param {[type]} table [description]</td></tr><tr><td class="line">574</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">575</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">576</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">577</td><td class="hits"></td><td class="source"> selectInsert: function(fields, table, options){</td></tr><tr class="miss"><td class="line">578</td><td class="hits">0</td><td class="source"> options = options || {};</td></tr><tr class="miss"><td class="line">579</td><td class="hits">0</td><td class="source"> this.model = options.model;</td></tr><tr class="miss"><td class="line">580</td><td class="hits">0</td><td class="source"> if (isString(fields)) {</td></tr><tr class="miss"><td class="line">581</td><td class="hits">0</td><td class="source"> fields = fields.split(',');</td></tr><tr><td class="line">582</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">583</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">584</td><td class="hits">0</td><td class="source"> fields = fields.map(function(item){</td></tr><tr class="miss"><td class="line">585</td><td class="hits">0</td><td class="source"> return self.parseKey(item);</td></tr><tr><td class="line">586</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">587</td><td class="hits">0</td><td class="source"> var sql = 'INSERT INTO ' + this.parseTable(options.table) + ' (' + fields.join(',') + ')';</td></tr><tr class="miss"><td class="line">588</td><td class="hits">0</td><td class="source"> sql += this.buildSelectSql(options);</td></tr><tr class="miss"><td class="line">589</td><td class="hits">0</td><td class="source"> return this.execute(sql);</td></tr><tr><td class="line">590</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">591</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">592</td><td class="hits"></td><td class="source"> * 删除记录</td></tr><tr><td class="line">593</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">594</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">595</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">596</td><td class="hits"></td><td class="source"> delete: function(options){</td></tr><tr class="miss"><td class="line">597</td><td class="hits">0</td><td class="source"> options = options || {};</td></tr><tr class="miss"><td class="line">598</td><td class="hits">0</td><td class="source"> this.model = options.model;</td></tr><tr class="miss"><td class="line">599</td><td class="hits">0</td><td class="source"> var sql = [</td></tr><tr><td class="line">600</td><td class="hits"></td><td class="source"> 'DELETE FROM ',</td></tr><tr><td class="line">601</td><td class="hits"></td><td class="source"> this.parseTable(options.table),</td></tr><tr><td class="line">602</td><td class="hits"></td><td class="source"> this.parseWhere(options.where),</td></tr><tr><td class="line">603</td><td class="hits"></td><td class="source"> this.parseOrder(options.order),</td></tr><tr><td class="line">604</td><td class="hits"></td><td class="source"> this.parseLimit(options.limit),</td></tr><tr><td class="line">605</td><td class="hits"></td><td class="source"> this.parseLock(options.lock),</td></tr><tr><td class="line">606</td><td class="hits"></td><td class="source"> this.parseComment(options.comment)</td></tr><tr><td class="line">607</td><td class="hits"></td><td class="source"> ].join('');</td></tr><tr class="miss"><td class="line">608</td><td class="hits">0</td><td class="source"> return this.execute(sql);</td></tr><tr><td class="line">609</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">610</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">611</td><td class="hits"></td><td class="source"> * 更新数据</td></tr><tr><td class="line">612</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">613</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">614</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">615</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">616</td><td class="hits"></td><td class="source"> update: function(data, options){</td></tr><tr class="miss"><td class="line">617</td><td class="hits">0</td><td class="source"> options = options || {};</td></tr><tr class="miss"><td class="line">618</td><td class="hits">0</td><td class="source"> this.model = options.model;</td></tr><tr class="miss"><td class="line">619</td><td class="hits">0</td><td class="source"> var sql = [</td></tr><tr><td class="line">620</td><td class="hits"></td><td class="source"> 'UPDATE ',</td></tr><tr><td class="line">621</td><td class="hits"></td><td class="source"> this.parseTable(options.table),</td></tr><tr><td class="line">622</td><td class="hits"></td><td class="source"> this.parseSet(data),</td></tr><tr><td class="line">623</td><td class="hits"></td><td class="source"> this.parseWhere(options.where),</td></tr><tr><td class="line">624</td><td class="hits"></td><td class="source"> this.parseOrder(options.order),</td></tr><tr><td class="line">625</td><td class="hits"></td><td class="source"> this.parseLimit(options.limit),</td></tr><tr><td class="line">626</td><td class="hits"></td><td class="source"> this.parseLock(options.lock),</td></tr><tr><td class="line">627</td><td class="hits"></td><td class="source"> this.parseComment(options.comment)</td></tr><tr><td class="line">628</td><td class="hits"></td><td class="source"> ].join('');</td></tr><tr class="miss"><td class="line">629</td><td class="hits">0</td><td class="source"> return this.execute(sql);</td></tr><tr><td class="line">630</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">631</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">632</td><td class="hits"></td><td class="source"> * 数据查询</td></tr><tr><td class="line">633</td><td class="hits"></td><td class="source"> * @todo 返回是个promise缓存调用需要修改</td></tr><tr><td class="line">634</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">635</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">636</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">637</td><td class="hits"></td><td class="source"> select: function(options){</td></tr><tr class="miss"><td class="line">638</td><td class="hits">0</td><td class="source"> var sql, cache;</td></tr><tr class="miss"><td class="line">639</td><td class="hits">0</td><td class="source"> if (isString(options) &amp;&amp; options.indexOf('SELECT') &gt; -1) {</td></tr><tr class="miss"><td class="line">640</td><td class="hits">0</td><td class="source"> sql = options;</td></tr><tr class="miss"><td class="line">641</td><td class="hits">0</td><td class="source"> cache = arguments[1];</td></tr><tr><td class="line">642</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">643</td><td class="hits">0</td><td class="source"> options = options || {};</td></tr><tr class="miss"><td class="line">644</td><td class="hits">0</td><td class="source"> this.model = options.model;</td></tr><tr class="miss"><td class="line">645</td><td class="hits">0</td><td class="source"> sql = this.buildSelectSql(options);</td></tr><tr class="miss"><td class="line">646</td><td class="hits">0</td><td class="source"> cache = options.cache;</td></tr><tr><td class="line">647</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">648</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">649</td><td class="hits">0</td><td class="source"> var cacheOn = !isEmpty(cache) &amp;&amp; C('db_cache_on');</td></tr><tr><td class="line">650</td><td class="hits"></td><td class="source"> //获取数据</td></tr><tr class="miss"><td class="line">651</td><td class="hits">0</td><td class="source"> function queryData(){</td></tr><tr class="miss"><td class="line">652</td><td class="hits">0</td><td class="source"> return self.query(sql).then(function(data){</td></tr><tr class="miss"><td class="line">653</td><td class="hits">0</td><td class="source"> if (cacheOn) {</td></tr><tr class="miss"><td class="line">654</td><td class="hits">0</td><td class="source"> S(key, data, cache);</td></tr><tr><td class="line">655</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">656</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">657</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">658</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">659</td><td class="hits">0</td><td class="source"> if (cacheOn) {</td></tr><tr class="miss"><td class="line">660</td><td class="hits">0</td><td class="source"> var key = isString(cache.key) &amp;&amp; cache.key ? cache.key : md5(sql);</td></tr><tr class="miss"><td class="line">661</td><td class="hits">0</td><td class="source"> return S(key, undefined, cache).then(function(value){</td></tr><tr class="miss"><td class="line">662</td><td class="hits">0</td><td class="source"> return value || queryData();</td></tr><tr><td class="line">663</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">664</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">665</td><td class="hits">0</td><td class="source"> return queryData();</td></tr><tr><td class="line">666</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">667</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">668</td><td class="hits"></td><td class="source"> * 转义字符</td></tr><tr><td class="line">669</td><td class="hits"></td><td class="source"> * @param {[type]} str [description]</td></tr><tr><td class="line">670</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">671</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">672</td><td class="hits"></td><td class="source"> escapeString: function(str){</td></tr><tr class="miss"><td class="line">673</td><td class="hits">0</td><td class="source"> if (!str) {</td></tr><tr class="miss"><td class="line">674</td><td class="hits">0</td><td class="source"> return '';</td></tr><tr><td class="line">675</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">676</td><td class="hits">0</td><td class="source"> return str.replace(/[\0\n\r\b\t\\\'\&quot;\x1a]/g, function(s) {</td></tr><tr class="miss"><td class="line">677</td><td class="hits">0</td><td class="source"> switch(s) {</td></tr><tr><td class="line">678</td><td class="hits"></td><td class="source"> case '\0': </td></tr><tr class="miss"><td class="line">679</td><td class="hits">0</td><td class="source"> return '\\0';</td></tr><tr><td class="line">680</td><td class="hits"></td><td class="source"> case '\n': </td></tr><tr class="miss"><td class="line">681</td><td class="hits">0</td><td class="source"> return '\\n';</td></tr><tr><td class="line">682</td><td class="hits"></td><td class="source"> case '\r': </td></tr><tr class="miss"><td class="line">683</td><td class="hits">0</td><td class="source"> return '\\r';</td></tr><tr><td class="line">684</td><td class="hits"></td><td class="source"> case '\b': </td></tr><tr class="miss"><td class="line">685</td><td class="hits">0</td><td class="source"> return '\\b';</td></tr><tr><td class="line">686</td><td class="hits"></td><td class="source"> case '\t': </td></tr><tr class="miss"><td class="line">687</td><td class="hits">0</td><td class="source"> return '\\t';</td></tr><tr><td class="line">688</td><td class="hits"></td><td class="source"> case '\x1a': </td></tr><tr class="miss"><td class="line">689</td><td class="hits">0</td><td class="source"> return '\\Z';</td></tr><tr><td class="line">690</td><td class="hits"></td><td class="source"> default: </td></tr><tr class="miss"><td class="line">691</td><td class="hits">0</td><td class="source"> return '\\'+s;</td></tr><tr><td class="line">692</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">693</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">694</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">695</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">696</td><td class="hits"></td><td class="source"> * 获取上次的sql语句</td></tr><tr><td class="line">697</td><td class="hits"></td><td class="source"> * @param {[type]} model [description]</td></tr><tr><td class="line">698</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">699</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">700</td><td class="hits"></td><td class="source"> getLastSql: function(model){</td></tr><tr class="miss"><td class="line">701</td><td class="hits">0</td><td class="source"> return model ? this.modelSql[model] : this.queryStr;</td></tr><tr><td class="line">702</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">703</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">704</td><td class="hits"></td><td class="source"> * 设置模型</td></tr><tr><td class="line">705</td><td class="hits"></td><td class="source"> * @param {[type]} model [description]</td></tr><tr><td class="line">706</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">707</td><td class="hits"></td><td class="source"> setModel: function(model){</td></tr><tr class="miss"><td class="line">708</td><td class="hits">0</td><td class="source"> this.model = model;</td></tr><tr class="miss"><td class="line">709</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">710</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">711</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">712</td><td class="hits"></td><td class="source">});</td></tr><tr><td class="line">713</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">714</td><td class="hits"></td><td class="source"> * 解析dsn</td></tr><tr><td class="line">715</td><td class="hits"></td><td class="source"> * 格式: mysql://username:passwd@localhost:3306/DbName</td></tr><tr><td class="line">716</td><td class="hits"></td><td class="source"> * @param string dsn [description]</td></tr><tr><td class="line">717</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">718</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">719</td><td class="hits">1</td><td class="source">Db.parseDSN = function(dsn){</td></tr><tr class="miss"><td class="line">720</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">721</td><td class="hits">0</td><td class="source"> if (!dsn) {</td></tr><tr class="miss"><td class="line">722</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">723</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">724</td><td class="hits">0</td><td class="source"> var info = url.parse(dsn);</td></tr><tr class="miss"><td class="line">725</td><td class="hits">0</td><td class="source"> var auth = (info.auth || '').split(':');</td></tr><tr class="miss"><td class="line">726</td><td class="hits">0</td><td class="source"> return {</td></tr><tr><td class="line">727</td><td class="hits"></td><td class="source"> 'dbms': info.protocol,</td></tr><tr><td class="line">728</td><td class="hits"></td><td class="source"> 'username': auth[0] || '',</td></tr><tr><td class="line">729</td><td class="hits"></td><td class="source"> 'password': auth[1] || '',</td></tr><tr><td class="line">730</td><td class="hits"></td><td class="source"> 'hostname': info.hostname || '',</td></tr><tr><td class="line">731</td><td class="hits"></td><td class="source"> 'hostport': info.port || '',</td></tr><tr><td class="line">732</td><td class="hits"></td><td class="source"> 'database': (info.pathname || '').substr(1),</td></tr><tr><td class="line">733</td><td class="hits"></td><td class="source"> 'dsn': ''</td></tr><tr><td class="line">734</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">735</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">736</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">737</td><td class="hits"></td><td class="source"> * 解析配置</td></tr><tr><td class="line">738</td><td class="hits"></td><td class="source"> * @param {[type]} config [description]</td></tr><tr><td class="line">739</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">740</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">741</td><td class="hits">1</td><td class="source">Db.parseConfig = function(config){</td></tr><tr class="miss"><td class="line">742</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">743</td><td class="hits">0</td><td class="source"> if (config &amp;&amp; isString(config)) {</td></tr><tr class="miss"><td class="line">744</td><td class="hits">0</td><td class="source"> return this.parseDSN(config);</td></tr><tr class="miss"><td class="line">745</td><td class="hits">0</td><td class="source"> }else if(isObject(config)){</td></tr><tr class="miss"><td class="line">746</td><td class="hits">0</td><td class="source"> return {</td></tr><tr><td class="line">747</td><td class="hits"></td><td class="source"> 'dbms': config.db_type || 'mysql',</td></tr><tr><td class="line">748</td><td class="hits"></td><td class="source"> 'username': config.db_user,</td></tr><tr><td class="line">749</td><td class="hits"></td><td class="source"> 'password': config.db_pwd,</td></tr><tr><td class="line">750</td><td class="hits"></td><td class="source"> 'hostname': config.db_host,</td></tr><tr><td class="line">751</td><td class="hits"></td><td class="source"> 'hostport': config.db_port,</td></tr><tr><td class="line">752</td><td class="hits"></td><td class="source"> 'database': config.db_name,</td></tr><tr><td class="line">753</td><td class="hits"></td><td class="source"> 'dsn': config.db_dsn,</td></tr><tr><td class="line">754</td><td class="hits"></td><td class="source"> 'params': config.db_params</td></tr><tr><td class="line">755</td><td class="hits"></td><td class="source"> };</td></tr><tr class="miss"><td class="line">756</td><td class="hits">0</td><td class="source"> }else if(!config){</td></tr><tr class="miss"><td class="line">757</td><td class="hits">0</td><td class="source"> if (C('db_dsn')) {</td></tr><tr class="miss"><td class="line">758</td><td class="hits">0</td><td class="source"> return this.parseDSN(C('db_dsn'));</td></tr><tr><td class="line">759</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">760</td><td class="hits">0</td><td class="source"> return {</td></tr><tr><td class="line">761</td><td class="hits"></td><td class="source"> 'dbms' : C('db_type'),</td></tr><tr><td class="line">762</td><td class="hits"></td><td class="source"> 'username' : C('db_user'),</td></tr><tr><td class="line">763</td><td class="hits"></td><td class="source"> 'password' : C('db_pwd'),</td></tr><tr><td class="line">764</td><td class="hits"></td><td class="source"> 'hostname' : C('db_host'),</td></tr><tr><td class="line">765</td><td class="hits"></td><td class="source"> 'hostport' : C('db_port'),</td></tr><tr><td class="line">766</td><td class="hits"></td><td class="source"> 'database' : C('db_name'),</td></tr><tr><td class="line">767</td><td class="hits"></td><td class="source"> 'dsn' : C('db_dsn'),</td></tr><tr><td class="line">768</td><td class="hits"></td><td class="source"> 'params' : C('db_params'),</td></tr><tr><td class="line">769</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">770</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">771</td><td class="hits">0</td><td class="source"> return config;</td></tr><tr><td class="line">772</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">773</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">774</td><td class="hits"></td><td class="source"> * 根据配置获取对应的数据库实例</td></tr><tr><td class="line">775</td><td class="hits"></td><td class="source"> * @param {[type]} config [description]</td></tr><tr><td class="line">776</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">777</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">778</td><td class="hits">1</td><td class="source">Db.getInstance = function(config){</td></tr><tr class="miss"><td class="line">779</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">780</td><td class="hits">0</td><td class="source"> config = this.parseConfig(config);</td></tr><tr class="miss"><td class="line">781</td><td class="hits">0</td><td class="source"> if (!config.dbms) {</td></tr><tr class="miss"><td class="line">782</td><td class="hits">0</td><td class="source"> console.log('no dbms config');</td></tr><tr class="miss"><td class="line">783</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">784</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">785</td><td class="hits"></td><td class="source"> //数据库类型</td></tr><tr class="miss"><td class="line">786</td><td class="hits">0</td><td class="source"> var dbType = config.dbms.toLowerCase();</td></tr><tr class="miss"><td class="line">787</td><td class="hits">0</td><td class="source"> dbType = dbType.substr(0, 1).toUpperCase() + dbType.substr(1);</td></tr><tr class="miss"><td class="line">788</td><td class="hits">0</td><td class="source"> var instance = thinkRequire(dbType + 'Db')(config);</td></tr><tr class="miss"><td class="line">789</td><td class="hits">0</td><td class="source"> instance.dbType = dbType.toUpperCase();</td></tr><tr class="miss"><td class="line">790</td><td class="hits">0</td><td class="source"> return instance;</td></tr><tr><td class="line">791</td><td class="hits"></td><td class="source">};</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Dispatcher.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Dispatcher.js</h2><div id="stats" class="high"><div class="percentage">87%</div><div class="sloc">47</div><div class="hits">41</div><div class="misses">6</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * 路由识别</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @type {Object}</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">var Dispatcher = module.exports = Class(function(){</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> * 初始化</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> * @param {[type]} http [description]</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> init: function(http){</td></tr><tr class="hit"><td class="line">14</td><td class="hits">1</td><td class="source"> this.http = http;</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> * 准备pathanem</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> preparePathName: function(){</td></tr><tr class="hit"><td class="line">21</td><td class="hits">1</td><td class="source"> var pathname = this.http.pathname.split('/').filter(function(item){</td></tr><tr class="hit"><td class="line">22</td><td class="hits">2</td><td class="source"> return item.trim();</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> }).join('/');</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> //去除pathname前缀</td></tr><tr class="hit"><td class="line">25</td><td class="hits">1</td><td class="source"> var prefix = C('url_pathname_prefix');</td></tr><tr class="hit"><td class="line">26</td><td class="hits">1</td><td class="source"> if (prefix &amp;&amp; pathname.indexOf(prefix) === 0) {</td></tr><tr class="miss"><td class="line">27</td><td class="hits">0</td><td class="source"> pathname = pathname.substr(prefix.length);</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> //判断URL后缀</td></tr><tr class="hit"><td class="line">30</td><td class="hits">1</td><td class="source"> var suffix = C('url_pathname_suffix');</td></tr><tr class="hit"><td class="line">31</td><td class="hits">1</td><td class="source"> if (suffix &amp;&amp; pathname.substr(0 - suffix.length) === suffix) {</td></tr><tr class="miss"><td class="line">32</td><td class="hits">0</td><td class="source"> pathname = pathname.substr(0, pathname.length - suffix.length);</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">34</td><td class="hits">1</td><td class="source"> this.http.pathname = pathname;</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> * 解析pathname</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">39</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> parsePathName: function(){</td></tr><tr class="hit"><td class="line">41</td><td class="hits">1</td><td class="source"> if (this.http.group) {</td></tr><tr class="miss"><td class="line">42</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">44</td><td class="hits">1</td><td class="source"> var paths = this.http.pathname.split('/');</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source"> //将group list变为小写</td></tr><tr class="hit"><td class="line">46</td><td class="hits">1</td><td class="source"> var groupList = C('app_group_list').map(function(item){</td></tr><tr class="hit"><td class="line">47</td><td class="hits">2</td><td class="source"> return item.toLowerCase();</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> });</td></tr><tr class="hit"><td class="line">49</td><td class="hits">1</td><td class="source"> var group = '';</td></tr><tr class="hit"><td class="line">50</td><td class="hits">1</td><td class="source"> if (groupList.length &amp;&amp; paths[0] &amp;&amp; groupList.indexOf(paths[0].toLowerCase()) &gt; -1) {</td></tr><tr class="miss"><td class="line">51</td><td class="hits">0</td><td class="source"> group = paths.shift();</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">53</td><td class="hits">1</td><td class="source"> var controller = paths.shift();</td></tr><tr class="hit"><td class="line">54</td><td class="hits">1</td><td class="source"> var action = paths.shift();</td></tr><tr><td class="line">55</td><td class="hits"></td><td class="source"> //解析剩余path的参数</td></tr><tr class="hit"><td class="line">56</td><td class="hits">1</td><td class="source"> if (paths.length) {</td></tr><tr class="miss"><td class="line">57</td><td class="hits">0</td><td class="source"> for(var i = 0,length = Math.ceil(paths.length) / 2; i &lt; length; i++){</td></tr><tr class="miss"><td class="line">58</td><td class="hits">0</td><td class="source"> this.http.get[paths[i * 2]] = paths[i * 2 + 1] || '';</td></tr><tr><td class="line">59</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">61</td><td class="hits">1</td><td class="source"> this.http.group = Dispatcher.getGroup(group);</td></tr><tr class="hit"><td class="line">62</td><td class="hits">1</td><td class="source"> this.http.controller = Dispatcher.getController(controller);</td></tr><tr class="hit"><td class="line">63</td><td class="hits">1</td><td class="source"> this.http.action = Dispatcher.getAction(action);</td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">65</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> * run</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">68</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">69</td><td class="hits"></td><td class="source"> run: function(){</td></tr><tr class="hit"><td class="line">70</td><td class="hits">1</td><td class="source"> var self = this;</td></tr><tr class="hit"><td class="line">71</td><td class="hits">1</td><td class="source"> return tag('resource_check', this.http).then(function(){</td></tr><tr class="hit"><td class="line">72</td><td class="hits">1</td><td class="source"> return self.preparePathName();</td></tr><tr><td class="line">73</td><td class="hits"></td><td class="source"> }).then(function(){</td></tr><tr class="hit"><td class="line">74</td><td class="hits">1</td><td class="source"> return tag('path_info', self.http);</td></tr><tr><td class="line">75</td><td class="hits"></td><td class="source"> }).then(function(){</td></tr><tr class="hit"><td class="line">76</td><td class="hits">1</td><td class="source"> return tag('route_check', self.http);</td></tr><tr><td class="line">77</td><td class="hits"></td><td class="source"> }).then(function(){</td></tr><tr class="hit"><td class="line">78</td><td class="hits">1</td><td class="source"> return self.parsePathName();</td></tr><tr><td class="line">79</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">80</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">81</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">82</td><td class="hits"></td><td class="source">});</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">84</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">85</td><td class="hits"></td><td class="source"> * 获取group</td></tr><tr><td class="line">86</td><td class="hits"></td><td class="source"> * @param {[type]} group [description]</td></tr><tr><td class="line">87</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">88</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">89</td><td class="hits">1</td><td class="source">Dispatcher.getGroup = function(group){</td></tr><tr class="hit"><td class="line">90</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">91</td><td class="hits">1</td><td class="source"> group = group || C('default_group');</td></tr><tr class="hit"><td class="line">92</td><td class="hits">1</td><td class="source"> return ucfirst(group);</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">94</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">95</td><td class="hits"></td><td class="source"> * 获取controller</td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source"> * @param {[type]} controller [description]</td></tr><tr><td class="line">97</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">98</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">99</td><td class="hits">1</td><td class="source">Dispatcher.getController = function(controller){</td></tr><tr class="hit"><td class="line">100</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">101</td><td class="hits">1</td><td class="source"> controller = controller || C('default_controller');</td></tr><tr class="hit"><td class="line">102</td><td class="hits">1</td><td class="source"> return ucfirst(controller);</td></tr><tr><td class="line">103</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">104</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">105</td><td class="hits"></td><td class="source"> * 获取action</td></tr><tr><td class="line">106</td><td class="hits"></td><td class="source"> * @param {[type]} action [description]</td></tr><tr><td class="line">107</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">108</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">109</td><td class="hits">1</td><td class="source">Dispatcher.getAction = function(action){</td></tr><tr class="hit"><td class="line">110</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">111</td><td class="hits">1</td><td class="source"> action = action || C('default_action');</td></tr><tr class="hit"><td class="line">112</td><td class="hits">1</td><td class="source"> return action;</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source">};</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Http.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Http.js</h2><div id="stats" class="low"><div class="percentage">40%</div><div class="sloc">135</div><div class="hits">55</div><div class="misses">80</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * 网络方法处理</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @type {Object}</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">var querystring = require('querystring');</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">var url = require('url');</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source">var cookie = thinkRequire('Cookie');</td></tr><tr class="hit"><td class="line">8</td><td class="hits">1</td><td class="source">var EventEmitter = require('events').EventEmitter;</td></tr><tr class="hit"><td class="line">9</td><td class="hits">1</td><td class="source">var multiparty = require('multiparty');</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">11</td><td class="hits">1</td><td class="source">var localIp = '127.0.0.1';</td></tr><tr class="hit"><td class="line">12</td><td class="hits">1</td><td class="source">module.exports = Class(function(){</td></tr><tr class="hit"><td class="line">13</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">14</td><td class="hits">1</td><td class="source"> var multiReg = /^multipart\/(form-data|related);\s*boundary=(?:&quot;([^&quot;]+)&quot;|([^;]+))$/i;</td></tr><tr class="hit"><td class="line">15</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> init: function(req, res){</td></tr><tr class="hit"><td class="line">17</td><td class="hits">1</td><td class="source"> this.req = req;</td></tr><tr class="hit"><td class="line">18</td><td class="hits">1</td><td class="source"> this.res = res;</td></tr><tr class="hit"><td class="line">19</td><td class="hits">1</td><td class="source"> this.http = new EventEmitter();</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> //记录当前请求的开始时间</td></tr><tr class="hit"><td class="line">21</td><td class="hits">1</td><td class="source"> this.http.startTime = Date.now();</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> run: function(callback){</td></tr><tr class="hit"><td class="line">24</td><td class="hits">1</td><td class="source"> this._request();</td></tr><tr class="hit"><td class="line">25</td><td class="hits">1</td><td class="source"> this._response();</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> //数组的indexOf要比字符串的indexOf略快</td></tr><tr class="hit"><td class="line">27</td><td class="hits">1</td><td class="source"> var methods = ['POST', 'PUT', 'PATCH'];</td></tr><tr class="hit"><td class="line">28</td><td class="hits">1</td><td class="source"> if (methods.indexOf(this.req.method) &gt; -1) {</td></tr><tr class="miss"><td class="line">29</td><td class="hits">0</td><td class="source"> return this.getPostData(callback);</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">31</td><td class="hits">1</td><td class="source"> return callback &amp;&amp; callback(this.http);</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> * 检测含有post数据</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> * @return {Boolean} [description]</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> hasPostData: function(){</td></tr><tr class="miss"><td class="line">38</td><td class="hits">0</td><td class="source"> if ('transfer-encoding' in this.req.headers) {</td></tr><tr class="miss"><td class="line">39</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">41</td><td class="hits">0</td><td class="source"> var contentLength = this.req.headers['content-length'] | 0;</td></tr><tr class="miss"><td class="line">42</td><td class="hits">0</td><td class="source"> return contentLength &gt; 0;</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source"> * 获取POST过来的数据包含上传的文件</td></tr><tr><td class="line">46</td><td class="hits"></td><td class="source"> * 依赖multiparty库</td></tr><tr><td class="line">47</td><td class="hits"></td><td class="source"> * @param {Function} callback [description]</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">49</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> getPostData: function(callback){</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> //没有post数据直接回调</td></tr><tr class="miss"><td class="line">52</td><td class="hits">0</td><td class="source"> if (!this.hasPostData()) {</td></tr><tr class="miss"><td class="line">53</td><td class="hits">0</td><td class="source"> return callback &amp;&amp; callback(this.http);</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">55</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">56</td><td class="hits">0</td><td class="source"> var contentType = (this.req.headers['content-type'] || '').split(';')[0].trim();</td></tr><tr class="miss"><td class="line">57</td><td class="hits">0</td><td class="source"> var deferred = getDefer();</td></tr><tr><td class="line">58</td><td class="hits"></td><td class="source"> //异步获取post数据</td></tr><tr class="miss"><td class="line">59</td><td class="hits">0</td><td class="source"> var postDataAsync = C('post_data_async');</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> //表单数据提交</td></tr><tr class="miss"><td class="line">61</td><td class="hits">0</td><td class="source"> if (multiReg.test(contentType)) {</td></tr><tr class="miss"><td class="line">62</td><td class="hits">0</td><td class="source"> var form = new multiparty.Form({</td></tr><tr><td class="line">63</td><td class="hits"></td><td class="source"> maxFieldsSize: C('post_max_fields_size'),</td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> maxFields: C('post_max_fields'),</td></tr><tr><td class="line">65</td><td class="hits"></td><td class="source"> maxFilesSize: C('post_max_file_size')</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">67</td><td class="hits">0</td><td class="source"> form.on('file', function(name, value){</td></tr><tr class="miss"><td class="line">68</td><td class="hits">0</td><td class="source"> self.http.file[name] = value;</td></tr><tr><td class="line">69</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">70</td><td class="hits">0</td><td class="source"> form.on('field', function(name, value){</td></tr><tr class="miss"><td class="line">71</td><td class="hits">0</td><td class="source"> self.http.post[name] = value;</td></tr><tr><td class="line">72</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">73</td><td class="hits">0</td><td class="source"> form.on('close', function(){</td></tr><tr class="miss"><td class="line">74</td><td class="hits">0</td><td class="source"> if (postDataAsync) {</td></tr><tr class="miss"><td class="line">75</td><td class="hits">0</td><td class="source"> return deferred.resolve(self.http.post);</td></tr><tr><td class="line">76</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">77</td><td class="hits">0</td><td class="source"> return callback &amp;&amp; callback(self.http);</td></tr><tr><td class="line">78</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">79</td><td class="hits"></td><td class="source"> //有错误后直接拒绝当前请求</td></tr><tr class="miss"><td class="line">80</td><td class="hits">0</td><td class="source"> form.on('error', function(){</td></tr><tr class="miss"><td class="line">81</td><td class="hits">0</td><td class="source"> self.res.statusCode = 413;</td></tr><tr class="miss"><td class="line">82</td><td class="hits">0</td><td class="source"> self.res.end();</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">84</td><td class="hits">0</td><td class="source"> form.parse(this.req);</td></tr><tr><td class="line">85</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">86</td><td class="hits">0</td><td class="source"> var buffer = '';</td></tr><tr class="miss"><td class="line">87</td><td class="hits">0</td><td class="source"> this.req.setEncoding(C('encoding'));</td></tr><tr class="miss"><td class="line">88</td><td class="hits">0</td><td class="source"> this.req.on('data', function(chunk){</td></tr><tr class="miss"><td class="line">89</td><td class="hits">0</td><td class="source"> buffer += chunk;</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">91</td><td class="hits">0</td><td class="source"> this.req.on('end', function(){</td></tr><tr><td class="line">92</td><td class="hits"></td><td class="source"> //json数据格式</td></tr><tr class="miss"><td class="line">93</td><td class="hits">0</td><td class="source"> var jsonConentType = C('post_json_content_type');</td></tr><tr class="miss"><td class="line">94</td><td class="hits">0</td><td class="source"> if (!isArray(jsonConentType)) {</td></tr><tr class="miss"><td class="line">95</td><td class="hits">0</td><td class="source"> jsonConentType = [jsonConentType];</td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">97</td><td class="hits">0</td><td class="source"> if (jsonConentType.indexOf(contentType) &gt; -1) {</td></tr><tr class="miss"><td class="line">98</td><td class="hits">0</td><td class="source"> self.http.post = JSON.parse(buffer) || {};</td></tr><tr><td class="line">99</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">100</td><td class="hits">0</td><td class="source"> self.http.post = querystring.parse(buffer) || {};</td></tr><tr><td class="line">101</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">102</td><td class="hits"></td><td class="source"> //请求内容</td></tr><tr class="miss"><td class="line">103</td><td class="hits">0</td><td class="source"> self.http.payload = buffer;</td></tr><tr class="miss"><td class="line">104</td><td class="hits">0</td><td class="source"> if (postDataAsync) {</td></tr><tr class="miss"><td class="line">105</td><td class="hits">0</td><td class="source"> return deferred.resolve(self.http.post);</td></tr><tr><td class="line">106</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">107</td><td class="hits">0</td><td class="source"> return callback &amp;&amp; callback(self.http);</td></tr><tr><td class="line">108</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">109</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">110</td><td class="hits">0</td><td class="source"> if (postDataAsync) {</td></tr><tr class="miss"><td class="line">111</td><td class="hits">0</td><td class="source"> self.http.postPromise = deferred.promise;</td></tr><tr class="miss"><td class="line">112</td><td class="hits">0</td><td class="source"> return callback &amp;&amp; callback(self.http);</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">114</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">115</td><td class="hits"></td><td class="source"> _request: function(){</td></tr><tr class="hit"><td class="line">116</td><td class="hits">1</td><td class="source"> var req = {</td></tr><tr><td class="line">117</td><td class="hits"></td><td class="source"> version: this.req.httpVersion,</td></tr><tr><td class="line">118</td><td class="hits"></td><td class="source"> method: this.req.method,</td></tr><tr><td class="line">119</td><td class="hits"></td><td class="source"> headers: this.req.headers,</td></tr><tr><td class="line">120</td><td class="hits"></td><td class="source"> getHeader: function(name){</td></tr><tr class="miss"><td class="line">121</td><td class="hits">0</td><td class="source"> return this.headers[name] || '';</td></tr><tr><td class="line">122</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">123</td><td class="hits"></td><td class="source"> post: {},</td></tr><tr><td class="line">124</td><td class="hits"></td><td class="source"> file: {},</td></tr><tr><td class="line">125</td><td class="hits"></td><td class="source"> ip: function(){</td></tr><tr class="miss"><td class="line">126</td><td class="hits">0</td><td class="source"> var ip = this.req.connection.remoteAddress || this.req.socket.remoteAddress;</td></tr><tr class="miss"><td class="line">127</td><td class="hits">0</td><td class="source"> if (ip &amp;&amp; ip !== localIp) {</td></tr><tr class="miss"><td class="line">128</td><td class="hits">0</td><td class="source"> return ip;</td></tr><tr><td class="line">129</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">130</td><td class="hits">0</td><td class="source"> return this.headers['x-forwarded-for'] || this.headers['x-real-ip'] || localIp;</td></tr><tr><td class="line">131</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">132</td><td class="hits"></td><td class="source"> cookie: cookie.parse(this.req.headers.cookie || '')</td></tr><tr><td class="line">133</td><td class="hits"></td><td class="source"> };</td></tr><tr class="hit"><td class="line">134</td><td class="hits">1</td><td class="source"> extend(this.http, req);</td></tr><tr><td class="line">135</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">136</td><td class="hits"></td><td class="source"> //解析url中的参数</td></tr><tr class="hit"><td class="line">137</td><td class="hits">1</td><td class="source"> var urlInfo = url.parse('//' + req.headers.host + this.req.url, true, true);</td></tr><tr class="hit"><td class="line">138</td><td class="hits">1</td><td class="source"> this.http.pathname = urlInfo.pathname;</td></tr><tr><td class="line">139</td><td class="hits"></td><td class="source"> //query只记录?后面的参数</td></tr><tr class="hit"><td class="line">140</td><td class="hits">1</td><td class="source"> this.http.query = urlInfo.query;</td></tr><tr><td class="line">141</td><td class="hits"></td><td class="source"> //get包含路由解析追加的参数</td></tr><tr class="hit"><td class="line">142</td><td class="hits">1</td><td class="source"> this.http.get = extend({}, urlInfo.query);</td></tr><tr><td class="line">143</td><td class="hits"></td><td class="source"> //主机名,带端口</td></tr><tr class="hit"><td class="line">144</td><td class="hits">1</td><td class="source"> this.http.host = urlInfo.host;</td></tr><tr><td class="line">145</td><td class="hits"></td><td class="source"> //主机名,不带端口</td></tr><tr class="hit"><td class="line">146</td><td class="hits">1</td><td class="source"> this.http.hostname = urlInfo.hostname;</td></tr><tr><td class="line">147</td><td class="hits"></td><td class="source"> //将原生的request对象放在http上方便后续在controller等地方使用</td></tr><tr class="hit"><td class="line">148</td><td class="hits">1</td><td class="source"> this.http.req = this.req;</td></tr><tr><td class="line">149</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">150</td><td class="hits"></td><td class="source"> _response: function(){</td></tr><tr class="hit"><td class="line">151</td><td class="hits">1</td><td class="source"> var res = {</td></tr><tr><td class="line">152</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">153</td><td class="hits"></td><td class="source"> * 一次请求下可能会发送多个Cookie所以这里不能立即发送</td></tr><tr><td class="line">154</td><td class="hits"></td><td class="source"> * 需要临时存起来,到输出内容前统一发送</td></tr><tr><td class="line">155</td><td class="hits"></td><td class="source"> * @type {Object}</td></tr><tr><td class="line">156</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">157</td><td class="hits"></td><td class="source"> _cookie: {}, </td></tr><tr><td class="line">158</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">159</td><td class="hits"></td><td class="source"> * 发送header</td></tr><tr><td class="line">160</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">161</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">162</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">163</td><td class="hits"></td><td class="source"> setHeader: function(name, value){</td></tr><tr class="hit"><td class="line">164</td><td class="hits">2</td><td class="source"> if (this.res.headersSent) {</td></tr><tr class="miss"><td class="line">165</td><td class="hits">0</td><td class="source"> if (APP_DEBUG) {</td></tr><tr class="miss"><td class="line">166</td><td class="hits">0</td><td class="source"> console.log('headers has been sent.', name, value);</td></tr><tr><td class="line">167</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">168</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">169</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">170</td><td class="hits">2</td><td class="source"> this.res.setHeader(name, value);</td></tr><tr><td class="line">171</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">172</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">173</td><td class="hits"></td><td class="source"> * 设置cookie</td></tr><tr><td class="line">174</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">175</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">176</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">177</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">178</td><td class="hits"></td><td class="source"> setCookie: function(name, value, options){</td></tr><tr class="miss"><td class="line">179</td><td class="hits">0</td><td class="source"> options = options || {};</td></tr><tr class="miss"><td class="line">180</td><td class="hits">0</td><td class="source"> if (typeof options === 'number') {</td></tr><tr class="miss"><td class="line">181</td><td class="hits">0</td><td class="source"> options = {timeout: options};</td></tr><tr><td class="line">182</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">183</td><td class="hits">0</td><td class="source"> var timeout = options.timeout;</td></tr><tr class="miss"><td class="line">184</td><td class="hits">0</td><td class="source"> if (timeout === undefined) {</td></tr><tr class="miss"><td class="line">185</td><td class="hits">0</td><td class="source"> timeout = C('cookie_timeout');</td></tr><tr><td class="line">186</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">187</td><td class="hits">0</td><td class="source"> delete options.timeout;</td></tr><tr><td class="line">188</td><td class="hits"></td><td class="source"> //if value is null, remove cookie</td></tr><tr class="miss"><td class="line">189</td><td class="hits">0</td><td class="source"> if (value === null) {</td></tr><tr class="miss"><td class="line">190</td><td class="hits">0</td><td class="source"> timeout = -1000;</td></tr><tr><td class="line">191</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">192</td><td class="hits">0</td><td class="source"> var defaultOptions = {</td></tr><tr><td class="line">193</td><td class="hits"></td><td class="source"> path: C('cookie_path'),</td></tr><tr><td class="line">194</td><td class="hits"></td><td class="source"> domain: C('cookie_domain'),</td></tr><tr><td class="line">195</td><td class="hits"></td><td class="source"> expires: new Date (Date.now() + timeout * 1000)</td></tr><tr><td class="line">196</td><td class="hits"></td><td class="source"> };</td></tr><tr class="miss"><td class="line">197</td><td class="hits">0</td><td class="source"> if (timeout === 0) {</td></tr><tr class="miss"><td class="line">198</td><td class="hits">0</td><td class="source"> delete defaultOptions.expires;</td></tr><tr><td class="line">199</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">200</td><td class="hits">0</td><td class="source"> for(var key in options){</td></tr><tr class="miss"><td class="line">201</td><td class="hits">0</td><td class="source"> defaultOptions[key.toLowerCase()] = options[key];</td></tr><tr><td class="line">202</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">203</td><td class="hits">0</td><td class="source"> defaultOptions.name = name;</td></tr><tr class="miss"><td class="line">204</td><td class="hits">0</td><td class="source"> defaultOptions.value = encodeURIComponent(value + '');</td></tr><tr class="miss"><td class="line">205</td><td class="hits">0</td><td class="source"> this._cookie[name] = defaultOptions;</td></tr><tr><td class="line">206</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">207</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">208</td><td class="hits"></td><td class="source"> * 将队列中的cookie发送出去</td></tr><tr><td class="line">209</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">210</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">211</td><td class="hits"></td><td class="source"> sendCookie: function(){</td></tr><tr class="hit"><td class="line">212</td><td class="hits">2</td><td class="source"> var cookies = Object.values(this._cookie).map(function(item){</td></tr><tr class="miss"><td class="line">213</td><td class="hits">0</td><td class="source"> return cookie.stringify(item.name, item.value, item);</td></tr><tr><td class="line">214</td><td class="hits"></td><td class="source"> });</td></tr><tr class="hit"><td class="line">215</td><td class="hits">2</td><td class="source"> if (cookies.length) {</td></tr><tr class="miss"><td class="line">216</td><td class="hits">0</td><td class="source"> this.setHeader('Set-Cookie', cookies);</td></tr><tr><td class="line">217</td><td class="hits"></td><td class="source"> //发送Cookie后不清除_cookie内容websocket里需要读取</td></tr><tr><td class="line">218</td><td class="hits"></td><td class="source"> //this._cookie = {};</td></tr><tr><td class="line">219</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">220</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">221</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">222</td><td class="hits"></td><td class="source"> * url跳转</td></tr><tr><td class="line">223</td><td class="hits"></td><td class="source"> * @param {[type]} url [description]</td></tr><tr><td class="line">224</td><td class="hits"></td><td class="source"> * @param {[type]} code [description]</td></tr><tr><td class="line">225</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">226</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">227</td><td class="hits"></td><td class="source"> redirect: function(url, code){</td></tr><tr class="miss"><td class="line">228</td><td class="hits">0</td><td class="source"> this.res.statusCode = code || 302;</td></tr><tr class="miss"><td class="line">229</td><td class="hits">0</td><td class="source"> this.setHeader('Location', url || '/');</td></tr><tr class="miss"><td class="line">230</td><td class="hits">0</td><td class="source"> this.end();</td></tr><tr><td class="line">231</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">232</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">233</td><td class="hits"></td><td class="source"> * 发送执行时间</td></tr><tr><td class="line">234</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">235</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">236</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">237</td><td class="hits"></td><td class="source"> sendTime: function(name){</td></tr><tr class="miss"><td class="line">238</td><td class="hits">0</td><td class="source"> var time = Date.now() - this.startTime;</td></tr><tr class="miss"><td class="line">239</td><td class="hits">0</td><td class="source"> this.setHeader('X-' + name, time + 'ms');</td></tr><tr><td class="line">240</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">241</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">242</td><td class="hits"></td><td class="source"> * 输出内容</td></tr><tr><td class="line">243</td><td class="hits"></td><td class="source"> * @param {[type]} obj [description]</td></tr><tr><td class="line">244</td><td class="hits"></td><td class="source"> * @param {[type]} encoding [description]</td></tr><tr><td class="line">245</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">246</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">247</td><td class="hits"></td><td class="source"> echo: function(obj, encoding){</td></tr><tr class="hit"><td class="line">248</td><td class="hits">1</td><td class="source"> this.sendCookie();</td></tr><tr class="hit"><td class="line">249</td><td class="hits">1</td><td class="source"> if (isArray(obj) || isObject(obj)) {</td></tr><tr class="miss"><td class="line">250</td><td class="hits">0</td><td class="source"> obj = JSON.stringify(obj);</td></tr><tr><td class="line">251</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">252</td><td class="hits">1</td><td class="source"> if (!isString(obj) &amp;&amp; !(obj instanceof Buffer)) {</td></tr><tr class="miss"><td class="line">253</td><td class="hits">0</td><td class="source"> obj += '';</td></tr><tr><td class="line">254</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">255</td><td class="hits">1</td><td class="source"> this.res.write(obj, encoding || C('encoding'));</td></tr><tr><td class="line">256</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">257</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">258</td><td class="hits"></td><td class="source"> * 结束URL</td></tr><tr><td class="line">259</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">260</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">261</td><td class="hits"></td><td class="source"> end: function(){</td></tr><tr class="hit"><td class="line">262</td><td class="hits">1</td><td class="source"> this.emit('beforeEnd', this);</td></tr><tr class="hit"><td class="line">263</td><td class="hits">1</td><td class="source"> this.sendCookie();</td></tr><tr class="hit"><td class="line">264</td><td class="hits">1</td><td class="source"> this.res.end();</td></tr><tr class="hit"><td class="line">265</td><td class="hits">1</td><td class="source"> this.emit('afterEnd', this);</td></tr><tr><td class="line">266</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">267</td><td class="hits"></td><td class="source"> };</td></tr><tr class="hit"><td class="line">268</td><td class="hits">1</td><td class="source"> extend(this.http, res);</td></tr><tr><td class="line">269</td><td class="hits"></td><td class="source"> //将原生的response对象放在http上方便后续controller等地方使用</td></tr><tr class="hit"><td class="line">270</td><td class="hits">1</td><td class="source"> this.http.res = this.res;</td></tr><tr><td class="line">271</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">272</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">273</td><td class="hits"></td><td class="source">});</td></tr><tr><td class="line">274</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">275</td><td class="hits"></td><td class="source"> * 获取默认的http信息</td></tr><tr><td class="line">276</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">277</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">278</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">279</td><td class="hits">1</td><td class="source">module.exports.getDefaultHttp = function(data){</td></tr><tr class="hit"><td class="line">280</td><td class="hits">2</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">281</td><td class="hits">2</td><td class="source"> data = data || {};</td></tr><tr class="hit"><td class="line">282</td><td class="hits">2</td><td class="source"> if (isString(data)) {</td></tr><tr class="hit"><td class="line">283</td><td class="hits">2</td><td class="source"> if (data[0] === '{') {</td></tr><tr class="miss"><td class="line">284</td><td class="hits">0</td><td class="source"> data = JSON.parse(data);</td></tr><tr class="hit"><td class="line">285</td><td class="hits">2</td><td class="source"> }else if (/^[\w]+\=/.test(data)) {</td></tr><tr class="miss"><td class="line">286</td><td class="hits">0</td><td class="source"> data = querystring.parse(data);</td></tr><tr><td class="line">287</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="hit"><td class="line">288</td><td class="hits">2</td><td class="source"> data = {url: data};</td></tr><tr><td class="line">289</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">290</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">291</td><td class="hits">2</td><td class="source"> var fn = function(){ </td></tr><tr class="hit"><td class="line">292</td><td class="hits">4</td><td class="source"> return '';</td></tr><tr><td class="line">293</td><td class="hits"></td><td class="source"> };</td></tr><tr class="hit"><td class="line">294</td><td class="hits">2</td><td class="source"> var url = data.url || '';</td></tr><tr class="hit"><td class="line">295</td><td class="hits">2</td><td class="source"> if (url.indexOf('/') !== 0) {</td></tr><tr class="miss"><td class="line">296</td><td class="hits">0</td><td class="source"> url = '/' + url;</td></tr><tr><td class="line">297</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">298</td><td class="hits">2</td><td class="source"> return {</td></tr><tr><td class="line">299</td><td class="hits"></td><td class="source"> req: {</td></tr><tr><td class="line">300</td><td class="hits"></td><td class="source"> httpVersion: '1.1',</td></tr><tr><td class="line">301</td><td class="hits"></td><td class="source"> method: data.method || 'GET',</td></tr><tr><td class="line">302</td><td class="hits"></td><td class="source"> url: url,</td></tr><tr><td class="line">303</td><td class="hits"></td><td class="source"> headers: extend({</td></tr><tr><td class="line">304</td><td class="hits"></td><td class="source"> host: data.host || localIp</td></tr><tr><td class="line">305</td><td class="hits"></td><td class="source"> }, data.headers || {}),</td></tr><tr><td class="line">306</td><td class="hits"></td><td class="source"> connection: {</td></tr><tr><td class="line">307</td><td class="hits"></td><td class="source"> remoteAddress: data.ip || localIp</td></tr><tr><td class="line">308</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">309</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">310</td><td class="hits"></td><td class="source"> res: {</td></tr><tr><td class="line">311</td><td class="hits"></td><td class="source"> end: data.end || data.close || fn,</td></tr><tr><td class="line">312</td><td class="hits"></td><td class="source"> write: data.write || data.send || fn,</td></tr><tr><td class="line">313</td><td class="hits"></td><td class="source"> setHeader: fn</td></tr><tr><td class="line">314</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">315</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">316</td><td class="hits"></td><td class="source">};</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Model.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Model.js</h2><div id="stats" class="terrible"><div class="percentage">5%</div><div class="sloc">440</div><div class="hits">24</div><div class="misses">416</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"><td class="line">1</td><td class="hits">1</td><td class="source">var util = require('util');</td></tr><tr class="hit"><td class="line">2</td><td class="hits">1</td><td class="source">var querystring = require('querystring');</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source">//数据库实例化对象</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">var dbInstances = {};</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source">//数据表的字段信息</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source">var tableFields = {};</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source">//db缓存数据</td></tr><tr class="hit"><td class="line">9</td><td class="hits">1</td><td class="source">var dbCacheData = {};</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> * Model类</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> * @type {[type]}</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">15</td><td class="hits">1</td><td class="source">var Model = module.exports = Class(function(){</td></tr><tr class="hit"><td class="line">16</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> //解析page参数</td></tr><tr class="hit"><td class="line">18</td><td class="hits">1</td><td class="source"> var parsePage = function(options){</td></tr><tr class="miss"><td class="line">19</td><td class="hits">0</td><td class="source"> if ('page' in options) {</td></tr><tr class="miss"><td class="line">20</td><td class="hits">0</td><td class="source"> var page = options.page + '';</td></tr><tr class="miss"><td class="line">21</td><td class="hits">0</td><td class="source"> var num = 0;</td></tr><tr class="miss"><td class="line">22</td><td class="hits">0</td><td class="source"> if (page.indexOf(',') &gt; -1) {</td></tr><tr class="miss"><td class="line">23</td><td class="hits">0</td><td class="source"> page = page.split(',');</td></tr><tr class="miss"><td class="line">24</td><td class="hits">0</td><td class="source"> num = parseInt(page[1], 10);</td></tr><tr class="miss"><td class="line">25</td><td class="hits">0</td><td class="source"> page = page[0];</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">27</td><td class="hits">0</td><td class="source"> num = num || C('db_nums_per_page');</td></tr><tr class="miss"><td class="line">28</td><td class="hits">0</td><td class="source"> page = parseInt(page, 10) || 1;</td></tr><tr class="miss"><td class="line">29</td><td class="hits">0</td><td class="source"> return {</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> page: page,</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> num: num</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">34</td><td class="hits">0</td><td class="source"> return {</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> page: 1,</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> num: C('db_nums_per_page')</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">39</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> * 字符串命名风格转换</td></tr><tr><td class="line">41</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> * @param {[type]} type [description]</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">45</td><td class="hits">1</td><td class="source"> var parseName = function(name, type){</td></tr><tr class="miss"><td class="line">46</td><td class="hits">0</td><td class="source"> name = (name + '').trim();</td></tr><tr class="miss"><td class="line">47</td><td class="hits">0</td><td class="source"> if (type) {</td></tr><tr class="miss"><td class="line">48</td><td class="hits">0</td><td class="source"> name = name.replace(/_([a-zA-Z])/g, function(a, b){</td></tr><tr class="miss"><td class="line">49</td><td class="hits">0</td><td class="source"> return b.toUpperCase();</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">51</td><td class="hits">0</td><td class="source"> return name.substr(0, 1).toUpperCase() + name.substr(1);</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> } else {</td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> //首字母如果是大写不转义为_x</td></tr><tr class="miss"><td class="line">54</td><td class="hits">0</td><td class="source"> if (name.length &gt;= 1) {</td></tr><tr class="miss"><td class="line">55</td><td class="hits">0</td><td class="source"> name = name.substr(0, 1).toLowerCase() + name.substr(1);</td></tr><tr><td class="line">56</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">57</td><td class="hits">0</td><td class="source"> return name.replace(/[A-Z]/g, function(a){</td></tr><tr class="miss"><td class="line">58</td><td class="hits">0</td><td class="source"> return '_' + a;</td></tr><tr><td class="line">59</td><td class="hits"></td><td class="source"> }).toLowerCase();</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">62</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">63</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> // 当前数据库操作对象</td></tr><tr><td class="line">65</td><td class="hits"></td><td class="source"> db: null,</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> // 主键名称</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> pk: 'id',</td></tr><tr><td class="line">68</td><td class="hits"></td><td class="source"> // 数据表前缀</td></tr><tr><td class="line">69</td><td class="hits"></td><td class="source"> tablePrefix: '',</td></tr><tr><td class="line">70</td><td class="hits"></td><td class="source"> // 数据库配置信息</td></tr><tr><td class="line">71</td><td class="hits"></td><td class="source"> config: null,</td></tr><tr><td class="line">72</td><td class="hits"></td><td class="source"> // 配置信息key</td></tr><tr><td class="line">73</td><td class="hits"></td><td class="source"> configKey: '',</td></tr><tr><td class="line">74</td><td class="hits"></td><td class="source"> // 模型名称</td></tr><tr><td class="line">75</td><td class="hits"></td><td class="source"> name: '',</td></tr><tr><td class="line">76</td><td class="hits"></td><td class="source"> // 数据库名称</td></tr><tr><td class="line">77</td><td class="hits"></td><td class="source"> dbName: '',</td></tr><tr><td class="line">78</td><td class="hits"></td><td class="source"> // 数据表名(不包含表前缀)</td></tr><tr><td class="line">79</td><td class="hits"></td><td class="source"> tableName: '',</td></tr><tr><td class="line">80</td><td class="hits"></td><td class="source"> // 实际数据表名(包含表前缀)</td></tr><tr><td class="line">81</td><td class="hits"></td><td class="source"> trueTableName: '',</td></tr><tr><td class="line">82</td><td class="hits"></td><td class="source"> // 数据表子度信息</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> fields: {},</td></tr><tr><td class="line">84</td><td class="hits"></td><td class="source"> // 数据信息</td></tr><tr><td class="line">85</td><td class="hits"></td><td class="source"> _data: {},</td></tr><tr><td class="line">86</td><td class="hits"></td><td class="source"> // 参数</td></tr><tr><td class="line">87</td><td class="hits"></td><td class="source"> _options: {},</td></tr><tr><td class="line">88</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">89</td><td class="hits"></td><td class="source"> * 取得DB类的实例对象 字段检查</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source"> * @access public</td></tr><tr><td class="line">91</td><td class="hits"></td><td class="source"> * @param string $name 模型名称</td></tr><tr><td class="line">92</td><td class="hits"></td><td class="source"> * @param string $tablePrefix 表前缀</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source"> * @param mixed config 数据库连接信息</td></tr><tr><td class="line">94</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">95</td><td class="hits"></td><td class="source"> init: function(name, tablePrefix, config){</td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source"> // 获取模型名称</td></tr><tr class="miss"><td class="line">97</td><td class="hits">0</td><td class="source"> if (name) {</td></tr><tr class="miss"><td class="line">98</td><td class="hits">0</td><td class="source"> if (name.indexOf('.') &gt; -1) {</td></tr><tr class="miss"><td class="line">99</td><td class="hits">0</td><td class="source"> name = name.split('.');</td></tr><tr class="miss"><td class="line">100</td><td class="hits">0</td><td class="source"> this.dbName = name[0];</td></tr><tr class="miss"><td class="line">101</td><td class="hits">0</td><td class="source"> this.name = name[1];</td></tr><tr><td class="line">102</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">103</td><td class="hits">0</td><td class="source"> this.name = name;</td></tr><tr><td class="line">104</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">105</td><td class="hits">0</td><td class="source"> }else if(!this.name){</td></tr><tr class="miss"><td class="line">106</td><td class="hits">0</td><td class="source"> this.getModelName();</td></tr><tr><td class="line">107</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">108</td><td class="hits">0</td><td class="source"> if (!isString(tablePrefix)) {</td></tr><tr class="miss"><td class="line">109</td><td class="hits">0</td><td class="source"> config = tablePrefix;</td></tr><tr class="miss"><td class="line">110</td><td class="hits">0</td><td class="source"> tablePrefix = undefined;</td></tr><tr><td class="line">111</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">112</td><td class="hits">0</td><td class="source"> this.config = config || '';</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source"> //设置数据表前缀</td></tr><tr class="miss"><td class="line">114</td><td class="hits">0</td><td class="source"> if (tablePrefix || this.config.db_prefix) {</td></tr><tr class="miss"><td class="line">115</td><td class="hits">0</td><td class="source"> this.tablePrefix = tablePrefix || this.config.db_prefix;</td></tr><tr><td class="line">116</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">117</td><td class="hits">0</td><td class="source"> if (!this.tablePrefix) {</td></tr><tr class="miss"><td class="line">118</td><td class="hits">0</td><td class="source"> this.tablePrefix = C('db_prefix');</td></tr><tr><td class="line">119</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">120</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">121</td><td class="hits"></td><td class="source"> //子类的init方法</td></tr><tr class="miss"><td class="line">122</td><td class="hits">0</td><td class="source"> if (this._init) {</td></tr><tr class="miss"><td class="line">123</td><td class="hits">0</td><td class="source"> this._init();</td></tr><tr><td class="line">124</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">125</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">126</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">127</td><td class="hits"></td><td class="source"> * 初始化数据库连接</td></tr><tr><td class="line">128</td><td class="hits"></td><td class="source"> * @access public</td></tr><tr><td class="line">129</td><td class="hits"></td><td class="source"> * @param integer $linkNum 连接序号</td></tr><tr><td class="line">130</td><td class="hits"></td><td class="source"> * @param mixed $config 数据库连接信息</td></tr><tr><td class="line">131</td><td class="hits"></td><td class="source"> * @param array $params 模型参数</td></tr><tr><td class="line">132</td><td class="hits"></td><td class="source"> * @return Model</td></tr><tr><td class="line">133</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">134</td><td class="hits"></td><td class="source"> initDb: function(){</td></tr><tr class="miss"><td class="line">135</td><td class="hits">0</td><td class="source"> if (this.db) {</td></tr><tr class="miss"><td class="line">136</td><td class="hits">0</td><td class="source"> return this.db;</td></tr><tr><td class="line">137</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">138</td><td class="hits">0</td><td class="source"> var config = this.config;</td></tr><tr class="miss"><td class="line">139</td><td class="hits">0</td><td class="source"> var configKey = md5(JSON.stringify(config));</td></tr><tr class="miss"><td class="line">140</td><td class="hits">0</td><td class="source"> if (!dbInstances[configKey]) {</td></tr><tr class="miss"><td class="line">141</td><td class="hits">0</td><td class="source"> if (config &amp;&amp; isString(config) &amp;&amp; config.indexOf('/') === -1) {</td></tr><tr class="miss"><td class="line">142</td><td class="hits">0</td><td class="source"> config = C(config);</td></tr><tr><td class="line">143</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">144</td><td class="hits">0</td><td class="source"> dbInstances[configKey] = thinkRequire('Db').getInstance(config);</td></tr><tr><td class="line">145</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">146</td><td class="hits">0</td><td class="source"> this.db = dbInstances[configKey];</td></tr><tr class="miss"><td class="line">147</td><td class="hits">0</td><td class="source"> this.configKey = configKey;</td></tr><tr class="miss"><td class="line">148</td><td class="hits">0</td><td class="source"> return this.db;</td></tr><tr><td class="line">149</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">150</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">151</td><td class="hits"></td><td class="source"> * 获取模型名</td></tr><tr><td class="line">152</td><td class="hits"></td><td class="source"> * @access public</td></tr><tr><td class="line">153</td><td class="hits"></td><td class="source"> * @return string</td></tr><tr><td class="line">154</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">155</td><td class="hits"></td><td class="source"> getModelName: function(){</td></tr><tr class="miss"><td class="line">156</td><td class="hits">0</td><td class="source"> if (this.name) {</td></tr><tr class="miss"><td class="line">157</td><td class="hits">0</td><td class="source"> return this.name;</td></tr><tr><td class="line">158</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">159</td><td class="hits">0</td><td class="source"> var filename = this.__filename || __filename;</td></tr><tr class="miss"><td class="line">160</td><td class="hits">0</td><td class="source"> var name = filename.split('/').pop();</td></tr><tr class="miss"><td class="line">161</td><td class="hits">0</td><td class="source"> this.name = name.substr(0, name.length - 8);</td></tr><tr class="miss"><td class="line">162</td><td class="hits">0</td><td class="source"> return this.name;</td></tr><tr><td class="line">163</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">164</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">165</td><td class="hits"></td><td class="source"> * 获取表名</td></tr><tr><td class="line">166</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">167</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">168</td><td class="hits"></td><td class="source"> getTableName: function(){</td></tr><tr class="miss"><td class="line">169</td><td class="hits">0</td><td class="source"> var tableName;</td></tr><tr class="miss"><td class="line">170</td><td class="hits">0</td><td class="source"> if (!this.trueTableName) {</td></tr><tr class="miss"><td class="line">171</td><td class="hits">0</td><td class="source"> tableName = this.tablePrefix || '';</td></tr><tr class="miss"><td class="line">172</td><td class="hits">0</td><td class="source"> tableName += this.tableName || parseName(this.getModelName());</td></tr><tr class="miss"><td class="line">173</td><td class="hits">0</td><td class="source"> this.trueTableName = tableName.toLowerCase();</td></tr><tr><td class="line">174</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">175</td><td class="hits">0</td><td class="source"> tableName = (this.dbName ? this.dbName + '.' : '') + this.trueTableName;</td></tr><tr class="miss"><td class="line">176</td><td class="hits">0</td><td class="source"> return tableName;</td></tr><tr><td class="line">177</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">178</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">179</td><td class="hits"></td><td class="source"> * 获取数据表信息</td></tr><tr><td class="line">180</td><td class="hits"></td><td class="source"> * @access protected</td></tr><tr><td class="line">181</td><td class="hits"></td><td class="source"> * @return Promise</td></tr><tr><td class="line">182</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">183</td><td class="hits"></td><td class="source"> getTableFields: function(table, all){</td></tr><tr class="miss"><td class="line">184</td><td class="hits">0</td><td class="source"> this.initDb();</td></tr><tr class="miss"><td class="line">185</td><td class="hits">0</td><td class="source"> if (table === true) {</td></tr><tr class="miss"><td class="line">186</td><td class="hits">0</td><td class="source"> table = undefined;</td></tr><tr class="miss"><td class="line">187</td><td class="hits">0</td><td class="source"> all = true;</td></tr><tr><td class="line">188</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">189</td><td class="hits">0</td><td class="source"> if (!isEmpty(this.fields)) {</td></tr><tr class="miss"><td class="line">190</td><td class="hits">0</td><td class="source"> return getPromise(all ? this.fields : this.fields._field);</td></tr><tr><td class="line">191</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">192</td><td class="hits">0</td><td class="source"> var tableName = table || this.getTableName();</td></tr><tr class="miss"><td class="line">193</td><td class="hits">0</td><td class="source"> var fields = tableFields[tableName];</td></tr><tr class="miss"><td class="line">194</td><td class="hits">0</td><td class="source"> if (!isEmpty(fields)) {</td></tr><tr class="miss"><td class="line">195</td><td class="hits">0</td><td class="source"> this.fields = fields;</td></tr><tr class="miss"><td class="line">196</td><td class="hits">0</td><td class="source"> return getPromise(all ? fields : fields._field);</td></tr><tr><td class="line">197</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">198</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr><td class="line">199</td><td class="hits"></td><td class="source"> //从数据表里查询字段信息</td></tr><tr class="miss"><td class="line">200</td><td class="hits">0</td><td class="source"> return this.flushFields().then(function(fields){</td></tr><tr class="miss"><td class="line">201</td><td class="hits">0</td><td class="source"> self.fields = fields;</td></tr><tr class="miss"><td class="line">202</td><td class="hits">0</td><td class="source"> if (C('db_fields_cache')) {</td></tr><tr class="miss"><td class="line">203</td><td class="hits">0</td><td class="source"> tableFields[tableName] = fields;</td></tr><tr><td class="line">204</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">205</td><td class="hits">0</td><td class="source"> return getPromise(all ? fields : fields._field);</td></tr><tr><td class="line">206</td><td class="hits"></td><td class="source"> }); </td></tr><tr><td class="line">207</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">208</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">209</td><td class="hits"></td><td class="source"> * 获取数据表信息</td></tr><tr><td class="line">210</td><td class="hits"></td><td class="source"> * @param {[type]} table [description]</td></tr><tr><td class="line">211</td><td class="hits"></td><td class="source"> * @return Promise [description]</td></tr><tr><td class="line">212</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">213</td><td class="hits"></td><td class="source"> flushFields: function(table){</td></tr><tr class="miss"><td class="line">214</td><td class="hits">0</td><td class="source"> table = table || this.getTableName();</td></tr><tr class="miss"><td class="line">215</td><td class="hits">0</td><td class="source"> return this.initDb().getFields(table).then(function(data){</td></tr><tr class="miss"><td class="line">216</td><td class="hits">0</td><td class="source"> var fields = {</td></tr><tr><td class="line">217</td><td class="hits"></td><td class="source"> '_field': Object.keys(data || {}),</td></tr><tr><td class="line">218</td><td class="hits"></td><td class="source"> '_autoinc': false,</td></tr><tr><td class="line">219</td><td class="hits"></td><td class="source"> '_unique': []</td></tr><tr><td class="line">220</td><td class="hits"></td><td class="source"> };</td></tr><tr class="miss"><td class="line">221</td><td class="hits">0</td><td class="source"> var types = {};</td></tr><tr class="miss"><td class="line">222</td><td class="hits">0</td><td class="source"> for(var key in data){</td></tr><tr class="miss"><td class="line">223</td><td class="hits">0</td><td class="source"> var val = data[key];</td></tr><tr class="miss"><td class="line">224</td><td class="hits">0</td><td class="source"> types[key] = val.type;</td></tr><tr class="miss"><td class="line">225</td><td class="hits">0</td><td class="source"> if (val.primary) {</td></tr><tr class="miss"><td class="line">226</td><td class="hits">0</td><td class="source"> fields._pk = key;</td></tr><tr class="miss"><td class="line">227</td><td class="hits">0</td><td class="source"> if (val.autoinc) {</td></tr><tr class="miss"><td class="line">228</td><td class="hits">0</td><td class="source"> fields._autoinc = true;</td></tr><tr><td class="line">229</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">230</td><td class="hits">0</td><td class="source"> }else if (val.unique) {</td></tr><tr class="miss"><td class="line">231</td><td class="hits">0</td><td class="source"> fields._unique.push(key);</td></tr><tr><td class="line">232</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">233</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">234</td><td class="hits">0</td><td class="source"> fields._type = types;</td></tr><tr class="miss"><td class="line">235</td><td class="hits">0</td><td class="source"> return fields;</td></tr><tr><td class="line">236</td><td class="hits"></td><td class="source"> })</td></tr><tr><td class="line">237</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">238</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">239</td><td class="hits"></td><td class="source"> * 获取类型为唯一的字段</td></tr><tr><td class="line">240</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">241</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">242</td><td class="hits"></td><td class="source"> getUniqueField: function(data){</td></tr><tr class="miss"><td class="line">243</td><td class="hits">0</td><td class="source"> var unqiueFileds = this.fields._unique;</td></tr><tr class="miss"><td class="line">244</td><td class="hits">0</td><td class="source"> var unqiue = '';</td></tr><tr class="miss"><td class="line">245</td><td class="hits">0</td><td class="source"> unqiueFileds.some(function(item){</td></tr><tr class="miss"><td class="line">246</td><td class="hits">0</td><td class="source"> if (!data || data[item]) {</td></tr><tr class="miss"><td class="line">247</td><td class="hits">0</td><td class="source"> unqiue = item;</td></tr><tr class="miss"><td class="line">248</td><td class="hits">0</td><td class="source"> return unqiue;</td></tr><tr><td class="line">249</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">250</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">251</td><td class="hits">0</td><td class="source"> return unqiue;</td></tr><tr><td class="line">252</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">253</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">254</td><td class="hits"></td><td class="source"> * 获取上一次操作的sql</td></tr><tr><td class="line">255</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">256</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">257</td><td class="hits"></td><td class="source"> getLastSql: function(){</td></tr><tr class="miss"><td class="line">258</td><td class="hits">0</td><td class="source"> return this.db.getLastSql();</td></tr><tr><td class="line">259</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">260</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">261</td><td class="hits"></td><td class="source"> * 获取主键名称</td></tr><tr><td class="line">262</td><td class="hits"></td><td class="source"> * @access public</td></tr><tr><td class="line">263</td><td class="hits"></td><td class="source"> * @return string</td></tr><tr><td class="line">264</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">265</td><td class="hits"></td><td class="source"> getPk: function(){</td></tr><tr class="miss"><td class="line">266</td><td class="hits">0</td><td class="source"> return this.fields._pk || this.pk;</td></tr><tr><td class="line">267</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">268</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">269</td><td class="hits"></td><td class="source"> * 缓存</td></tr><tr><td class="line">270</td><td class="hits"></td><td class="source"> * @param {[type]} key [description]</td></tr><tr><td class="line">271</td><td class="hits"></td><td class="source"> * @param {[type]} expire [description]</td></tr><tr><td class="line">272</td><td class="hits"></td><td class="source"> * @param {[type]} type [description]</td></tr><tr><td class="line">273</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">274</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">275</td><td class="hits"></td><td class="source"> cache: function(key, timeout){</td></tr><tr class="miss"><td class="line">276</td><td class="hits">0</td><td class="source"> if (key === undefined) {</td></tr><tr class="miss"><td class="line">277</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">278</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">279</td><td class="hits">0</td><td class="source"> var options = this.getCacheOptions(key, timeout);</td></tr><tr class="miss"><td class="line">280</td><td class="hits">0</td><td class="source"> this._options.cache = options;</td></tr><tr class="miss"><td class="line">281</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">282</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">283</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">284</td><td class="hits"></td><td class="source"> * 获取缓存的选项</td></tr><tr><td class="line">285</td><td class="hits"></td><td class="source"> * @param {[type]} key [description]</td></tr><tr><td class="line">286</td><td class="hits"></td><td class="source"> * @param {[type]} timeout [description]</td></tr><tr><td class="line">287</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">288</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">289</td><td class="hits"></td><td class="source"> getCacheOptions: function(key, timeout, type){</td></tr><tr class="miss"><td class="line">290</td><td class="hits">0</td><td class="source"> if (isObject(key)) {</td></tr><tr class="miss"><td class="line">291</td><td class="hits">0</td><td class="source"> return key;</td></tr><tr><td class="line">292</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">293</td><td class="hits">0</td><td class="source"> if (isNumber(key)) {</td></tr><tr class="miss"><td class="line">294</td><td class="hits">0</td><td class="source"> timeout = key;</td></tr><tr class="miss"><td class="line">295</td><td class="hits">0</td><td class="source"> key = '';</td></tr><tr><td class="line">296</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">297</td><td class="hits">0</td><td class="source"> var cacheType = type === undefined ? C('db_cache_type') : type;</td></tr><tr class="miss"><td class="line">298</td><td class="hits">0</td><td class="source"> var options = {</td></tr><tr><td class="line">299</td><td class="hits"></td><td class="source"> key: key,</td></tr><tr><td class="line">300</td><td class="hits"></td><td class="source"> timeout: timeout || C('db_cache_timeout'),</td></tr><tr><td class="line">301</td><td class="hits"></td><td class="source"> type: cacheType,</td></tr><tr><td class="line">302</td><td class="hits"></td><td class="source"> gcType: 'dbCache'</td></tr><tr><td class="line">303</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">304</td><td class="hits">0</td><td class="source"> if (cacheType === 'File') {</td></tr><tr class="miss"><td class="line">305</td><td class="hits">0</td><td class="source"> options.cache_path = C('db_cache_path');</td></tr><tr><td class="line">306</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">307</td><td class="hits">0</td><td class="source"> options.cacheData = dbCacheData;</td></tr><tr><td class="line">308</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">309</td><td class="hits">0</td><td class="source"> return options;</td></tr><tr><td class="line">310</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">311</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">312</td><td class="hits"></td><td class="source"> * 指定查询数量</td></tr><tr><td class="line">313</td><td class="hits"></td><td class="source"> * @param {[type]} offset [description]</td></tr><tr><td class="line">314</td><td class="hits"></td><td class="source"> * @param {[type]} length [description]</td></tr><tr><td class="line">315</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">316</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">317</td><td class="hits"></td><td class="source"> limit: function(offset, length){</td></tr><tr class="miss"><td class="line">318</td><td class="hits">0</td><td class="source"> this._options.limit = length === undefined ? offset : offset + ',' + length;</td></tr><tr class="miss"><td class="line">319</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">320</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">321</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">322</td><td class="hits"></td><td class="source"> * 指定分页</td></tr><tr><td class="line">323</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">324</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">325</td><td class="hits"></td><td class="source"> page: function(page, listRows){</td></tr><tr class="miss"><td class="line">326</td><td class="hits">0</td><td class="source"> this._options.page = listRows === undefined ? page : page + ',' + listRows;</td></tr><tr class="miss"><td class="line">327</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">328</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">329</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">330</td><td class="hits"></td><td class="source"> * where条件</td></tr><tr><td class="line">331</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">332</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">333</td><td class="hits"></td><td class="source"> where: function(where){</td></tr><tr class="miss"><td class="line">334</td><td class="hits">0</td><td class="source"> if (isString(where)) {</td></tr><tr class="miss"><td class="line">335</td><td class="hits">0</td><td class="source"> where = {_string: where};</td></tr><tr><td class="line">336</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">337</td><td class="hits">0</td><td class="source"> this._options.where = extend(this._options.where || {}, where);</td></tr><tr class="miss"><td class="line">338</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">339</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">340</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">341</td><td class="hits"></td><td class="source"> * 要查询的字段</td></tr><tr><td class="line">342</td><td class="hits"></td><td class="source"> * @param {[type]} field [description]</td></tr><tr><td class="line">343</td><td class="hits"></td><td class="source"> * @param {[type]} reverse [description]</td></tr><tr><td class="line">344</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">345</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">346</td><td class="hits"></td><td class="source"> field: function(field, reverse){</td></tr><tr class="miss"><td class="line">347</td><td class="hits">0</td><td class="source"> if (isArray(field)) {</td></tr><tr class="miss"><td class="line">348</td><td class="hits">0</td><td class="source"> field = field.join(',');</td></tr><tr class="miss"><td class="line">349</td><td class="hits">0</td><td class="source"> }else if (!field) {</td></tr><tr class="miss"><td class="line">350</td><td class="hits">0</td><td class="source"> field = '*';</td></tr><tr><td class="line">351</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">352</td><td class="hits">0</td><td class="source"> this._options.field = field;</td></tr><tr class="miss"><td class="line">353</td><td class="hits">0</td><td class="source"> this._options.fieldReverse = reverse;</td></tr><tr class="miss"><td class="line">354</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">355</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">356</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">357</td><td class="hits"></td><td class="source"> * 联合查询</td></tr><tr><td class="line">358</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">359</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">360</td><td class="hits"></td><td class="source"> union: function(union){</td></tr><tr class="miss"><td class="line">361</td><td class="hits">0</td><td class="source"> if (!this._options.union) {</td></tr><tr class="miss"><td class="line">362</td><td class="hits">0</td><td class="source"> this._options.union = [];</td></tr><tr><td class="line">363</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">364</td><td class="hits">0</td><td class="source"> this._options.union.push(union);</td></tr><tr class="miss"><td class="line">365</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">366</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">367</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">368</td><td class="hits"></td><td class="source"> * 联合查询</td></tr><tr><td class="line">369</td><td class="hits"></td><td class="source"> * @param {[type]} join [description]</td></tr><tr><td class="line">370</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">371</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">372</td><td class="hits"></td><td class="source"> join: function(join){</td></tr><tr class="miss"><td class="line">373</td><td class="hits">0</td><td class="source"> if (isArray(join)) {</td></tr><tr class="miss"><td class="line">374</td><td class="hits">0</td><td class="source"> this._options.join = join;</td></tr><tr><td class="line">375</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">376</td><td class="hits">0</td><td class="source"> if (!this._options.join) {</td></tr><tr class="miss"><td class="line">377</td><td class="hits">0</td><td class="source"> this._options.join = [];</td></tr><tr><td class="line">378</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">379</td><td class="hits">0</td><td class="source"> this._options.join.push(join);</td></tr><tr><td class="line">380</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">381</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">382</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">383</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">384</td><td class="hits"></td><td class="source"> * 生成查询SQL 可用于子查询</td></tr><tr><td class="line">385</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">386</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">387</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">388</td><td class="hits"></td><td class="source"> buildSql: function(options){</td></tr><tr class="miss"><td class="line">389</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">390</td><td class="hits">0</td><td class="source"> return this.parseOptions(options).then(function(options){</td></tr><tr class="miss"><td class="line">391</td><td class="hits">0</td><td class="source"> return '( ' + self.db.buildSelectSql(options) + ' )';</td></tr><tr><td class="line">392</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">393</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">394</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">395</td><td class="hits"></td><td class="source"> * 解析参数</td></tr><tr><td class="line">396</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">397</td><td class="hits"></td><td class="source"> * @return promise [description]</td></tr><tr><td class="line">398</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">399</td><td class="hits"></td><td class="source"> parseOptions: function(options, extraOptions){</td></tr><tr class="miss"><td class="line">400</td><td class="hits">0</td><td class="source"> options = extend({}, this._options, this.parseWhereOptions(options), extraOptions);</td></tr><tr><td class="line">401</td><td class="hits"></td><td class="source"> // 查询过后清空sql表达式组装 避免影响下次查询</td></tr><tr class="miss"><td class="line">402</td><td class="hits">0</td><td class="source"> this._options = {};</td></tr><tr class="miss"><td class="line">403</td><td class="hits">0</td><td class="source"> options.table = options.table || this.getTableName();</td></tr><tr class="miss"><td class="line">404</td><td class="hits">0</td><td class="source"> options.model = this.name;</td></tr><tr class="miss"><td class="line">405</td><td class="hits">0</td><td class="source"> var promise = this.getTableFields(options.table);</td></tr><tr><td class="line">406</td><td class="hits"></td><td class="source"> //数据表别名</td></tr><tr class="miss"><td class="line">407</td><td class="hits">0</td><td class="source"> if (options.alias) {</td></tr><tr class="miss"><td class="line">408</td><td class="hits">0</td><td class="source"> options.table += ' ' + options.alias;</td></tr><tr><td class="line">409</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">410</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">411</td><td class="hits">0</td><td class="source"> var keyReg = /[\.\|\&amp;]/;</td></tr><tr class="miss"><td class="line">412</td><td class="hits">0</td><td class="source"> return promise.then(function(fields){</td></tr><tr><td class="line">413</td><td class="hits"></td><td class="source"> // 字段类型验证</td></tr><tr class="miss"><td class="line">414</td><td class="hits">0</td><td class="source"> if (isObject(options.where) &amp;&amp; !isEmpty(fields)) {</td></tr><tr><td class="line">415</td><td class="hits"></td><td class="source"> // 对数组查询条件进行字段类型检查</td></tr><tr class="miss"><td class="line">416</td><td class="hits">0</td><td class="source"> for(var key in options.where){</td></tr><tr class="miss"><td class="line">417</td><td class="hits">0</td><td class="source"> var val = options.where[key];</td></tr><tr class="miss"><td class="line">418</td><td class="hits">0</td><td class="source"> key = key.trim();</td></tr><tr class="miss"><td class="line">419</td><td class="hits">0</td><td class="source"> if (fields.indexOf(key) &gt; -1) {</td></tr><tr class="miss"><td class="line">420</td><td class="hits">0</td><td class="source"> if (isScalar(val)) {</td></tr><tr class="miss"><td class="line">421</td><td class="hits">0</td><td class="source"> options.where = self.parseType(options.where, key);</td></tr><tr><td class="line">422</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">423</td><td class="hits">0</td><td class="source"> }else if(key.substr(0, 1) !== '_' &amp;&amp; !keyReg.test(key)){</td></tr><tr class="miss"><td class="line">424</td><td class="hits">0</td><td class="source"> delete options.where[key];</td></tr><tr><td class="line">425</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">426</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">427</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">428</td><td class="hits"></td><td class="source"> //field反选</td></tr><tr class="miss"><td class="line">429</td><td class="hits">0</td><td class="source"> if (options.field &amp;&amp; options.fieldReverse) {</td></tr><tr class="miss"><td class="line">430</td><td class="hits">0</td><td class="source"> var optionsField = options.field.split(',');</td></tr><tr class="miss"><td class="line">431</td><td class="hits">0</td><td class="source"> options.field = fields.filter(function(item){</td></tr><tr class="miss"><td class="line">432</td><td class="hits">0</td><td class="source"> if (optionsField.indexOf(item) &gt; -1) {</td></tr><tr class="miss"><td class="line">433</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">434</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">435</td><td class="hits">0</td><td class="source"> return item;</td></tr><tr><td class="line">436</td><td class="hits"></td><td class="source"> }).join(',');</td></tr><tr><td class="line">437</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">438</td><td class="hits">0</td><td class="source"> return self._optionsFilter(options, fields);</td></tr><tr><td class="line">439</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">440</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">441</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">442</td><td class="hits"></td><td class="source"> * 选项过滤器</td></tr><tr><td class="line">443</td><td class="hits"></td><td class="source"> * 具体的Model类里进行实现</td></tr><tr><td class="line">444</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">445</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">446</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">447</td><td class="hits"></td><td class="source"> _optionsFilter: function(options){</td></tr><tr class="miss"><td class="line">448</td><td class="hits">0</td><td class="source"> return options;</td></tr><tr><td class="line">449</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">450</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">451</td><td class="hits"></td><td class="source"> * 数据类型检测</td></tr><tr><td class="line">452</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">453</td><td class="hits"></td><td class="source"> * @param {[type]} key [description]</td></tr><tr><td class="line">454</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">455</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">456</td><td class="hits"></td><td class="source"> parseType: function(data, key){</td></tr><tr class="miss"><td class="line">457</td><td class="hits">0</td><td class="source"> var fieldType = this.fields._type[key] || '';</td></tr><tr class="miss"><td class="line">458</td><td class="hits">0</td><td class="source"> if (fieldType.indexOf('bigint') === -1 &amp;&amp; fieldType.indexOf('int') &gt; -1) {</td></tr><tr class="miss"><td class="line">459</td><td class="hits">0</td><td class="source"> data[key] = parseInt(data[key], 10) || 0;</td></tr><tr class="miss"><td class="line">460</td><td class="hits">0</td><td class="source"> }else if(fieldType.indexOf('double') &gt; -1 || fieldType.indexOf('float') &gt; -1){</td></tr><tr class="miss"><td class="line">461</td><td class="hits">0</td><td class="source"> data[key] = parseFloat(data[key]) || 0.0;</td></tr><tr class="miss"><td class="line">462</td><td class="hits">0</td><td class="source"> }else if(fieldType.indexOf('bool') &gt; -1){</td></tr><tr class="miss"><td class="line">463</td><td class="hits">0</td><td class="source"> data[key] = !! data[key];</td></tr><tr><td class="line">464</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">465</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">466</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">467</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">468</td><td class="hits"></td><td class="source"> * 对插入到数据库中的数据进行处理要在parseOptions后执行</td></tr><tr><td class="line">469</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">470</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">471</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">472</td><td class="hits"></td><td class="source"> parseData: function(data){</td></tr><tr class="miss"><td class="line">473</td><td class="hits">0</td><td class="source"> data = extend({}, data);</td></tr><tr class="miss"><td class="line">474</td><td class="hits">0</td><td class="source"> var key;</td></tr><tr class="miss"><td class="line">475</td><td class="hits">0</td><td class="source"> if (!isEmpty(this.fields)) {</td></tr><tr class="miss"><td class="line">476</td><td class="hits">0</td><td class="source"> for(key in data){</td></tr><tr class="miss"><td class="line">477</td><td class="hits">0</td><td class="source"> var val = data[key];</td></tr><tr class="miss"><td class="line">478</td><td class="hits">0</td><td class="source"> if (this.fields._field.indexOf(key) === -1) {</td></tr><tr class="miss"><td class="line">479</td><td class="hits">0</td><td class="source"> delete data[key];</td></tr><tr class="miss"><td class="line">480</td><td class="hits">0</td><td class="source"> }else if(isScalar(val)){</td></tr><tr class="miss"><td class="line">481</td><td class="hits">0</td><td class="source"> data = this.parseType(data, key);</td></tr><tr><td class="line">482</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">483</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">484</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">485</td><td class="hits"></td><td class="source"> //安全过滤</td></tr><tr class="miss"><td class="line">486</td><td class="hits">0</td><td class="source"> if (typeof this._options.filter === 'function') {</td></tr><tr class="miss"><td class="line">487</td><td class="hits">0</td><td class="source"> for(key in data){</td></tr><tr class="miss"><td class="line">488</td><td class="hits">0</td><td class="source"> data[key] = this._options.filter.call(this, key, data[key]);</td></tr><tr><td class="line">489</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">490</td><td class="hits">0</td><td class="source"> delete this._options.filter;</td></tr><tr><td class="line">491</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">492</td><td class="hits">0</td><td class="source"> data = this._dataFilter(data);</td></tr><tr class="miss"><td class="line">493</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">494</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">495</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">496</td><td class="hits"></td><td class="source"> * 数据过滤器</td></tr><tr><td class="line">497</td><td class="hits"></td><td class="source"> * 具体的Model类里进行实现</td></tr><tr><td class="line">498</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">499</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">500</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">501</td><td class="hits"></td><td class="source"> _dataFilter: function(data){</td></tr><tr class="miss"><td class="line">502</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">503</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">504</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">505</td><td class="hits"></td><td class="source"> * 数据插入之前操作可以返回一个promise</td></tr><tr><td class="line">506</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">507</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">508</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">509</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">510</td><td class="hits"></td><td class="source"> _beforeAdd: function(data){</td></tr><tr class="miss"><td class="line">511</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">512</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">513</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">514</td><td class="hits"></td><td class="source"> * 数据插入之后操作可以返回一个promise</td></tr><tr><td class="line">515</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">516</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">517</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">518</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">519</td><td class="hits"></td><td class="source"> _afterAdd: function(data){</td></tr><tr class="miss"><td class="line">520</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">521</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">522</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">523</td><td class="hits"></td><td class="source"> * 添加一条数据</td></tr><tr><td class="line">524</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">525</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">526</td><td class="hits"></td><td class="source"> * @param int 返回插入的id</td></tr><tr><td class="line">527</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">528</td><td class="hits"></td><td class="source"> add: function(data, options, replace){</td></tr><tr><td class="line">529</td><td class="hits"></td><td class="source"> //copy data</td></tr><tr class="miss"><td class="line">530</td><td class="hits">0</td><td class="source"> data = extend({}, data);</td></tr><tr class="miss"><td class="line">531</td><td class="hits">0</td><td class="source"> if (isEmpty(data)) {</td></tr><tr class="miss"><td class="line">532</td><td class="hits">0</td><td class="source"> if (this._data) {</td></tr><tr class="miss"><td class="line">533</td><td class="hits">0</td><td class="source"> data = this._data;</td></tr><tr class="miss"><td class="line">534</td><td class="hits">0</td><td class="source"> this._data = {};</td></tr><tr><td class="line">535</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">536</td><td class="hits">0</td><td class="source"> return getPromise(L('_DATA_TYPE_INVALID_'), true);</td></tr><tr><td class="line">537</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">538</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">539</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr><td class="line">540</td><td class="hits"></td><td class="source"> //解析后的选项</td></tr><tr class="miss"><td class="line">541</td><td class="hits">0</td><td class="source"> var parsedOptions = {};</td></tr><tr><td class="line">542</td><td class="hits"></td><td class="source"> //解析后的数据</td></tr><tr class="miss"><td class="line">543</td><td class="hits">0</td><td class="source"> var parsedData = {};</td></tr><tr class="miss"><td class="line">544</td><td class="hits">0</td><td class="source"> return this.parseOptions(options).then(function(options){</td></tr><tr class="miss"><td class="line">545</td><td class="hits">0</td><td class="source"> parsedOptions = options;</td></tr><tr class="miss"><td class="line">546</td><td class="hits">0</td><td class="source"> return self._beforeAdd(data, parsedOptions);</td></tr><tr><td class="line">547</td><td class="hits"></td><td class="source"> }).then(function(data){</td></tr><tr class="miss"><td class="line">548</td><td class="hits">0</td><td class="source"> parsedData = data;</td></tr><tr class="miss"><td class="line">549</td><td class="hits">0</td><td class="source"> data = self.parseData(data);</td></tr><tr class="miss"><td class="line">550</td><td class="hits">0</td><td class="source"> return self.db.insert(data, parsedOptions, replace);</td></tr><tr><td class="line">551</td><td class="hits"></td><td class="source"> }).then(function(){</td></tr><tr class="miss"><td class="line">552</td><td class="hits">0</td><td class="source"> parsedData[self.getPk()] = self.db.getLastInsertId();</td></tr><tr class="miss"><td class="line">553</td><td class="hits">0</td><td class="source"> return self._afterAdd(parsedData, parsedOptions);</td></tr><tr><td class="line">554</td><td class="hits"></td><td class="source"> }).then(function(){</td></tr><tr class="miss"><td class="line">555</td><td class="hits">0</td><td class="source"> return parsedData[self.getPk()];</td></tr><tr><td class="line">556</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">557</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">558</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">559</td><td class="hits"></td><td class="source"> * 如果当前条件的数据不存在,才添加</td></tr><tr><td class="line">560</td><td class="hits"></td><td class="source"> * @param {[type]} data 要插入的数据</td></tr><tr><td class="line">561</td><td class="hits"></td><td class="source"> * @param {[type]} where where条件</td></tr><tr><td class="line">562</td><td class="hits"></td><td class="source"> * @param boolean returnType 返回值是否包含type</td></tr><tr><td class="line">563</td><td class="hits"></td><td class="source"> * @return {[type]} promise</td></tr><tr><td class="line">564</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">565</td><td class="hits"></td><td class="source"> thenAdd: function(data, where, returnType){</td></tr><tr class="miss"><td class="line">566</td><td class="hits">0</td><td class="source"> this.where(where);</td></tr><tr class="miss"><td class="line">567</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">568</td><td class="hits">0</td><td class="source"> return this.find().then(function(findData){</td></tr><tr class="miss"><td class="line">569</td><td class="hits">0</td><td class="source"> if (!isEmpty(findData)) {</td></tr><tr class="miss"><td class="line">570</td><td class="hits">0</td><td class="source"> var idValue = findData[self.getPk()];</td></tr><tr class="miss"><td class="line">571</td><td class="hits">0</td><td class="source"> return returnType ? getObject([self.getPk(), 'type'], [idValue, 'exist']) : idValue;</td></tr><tr><td class="line">572</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">573</td><td class="hits">0</td><td class="source"> return self.add(data).then(function(insertId){</td></tr><tr class="miss"><td class="line">574</td><td class="hits">0</td><td class="source"> return returnType ? getObject([self.getPk(), 'type'], [insertId, 'add']) : insertId;</td></tr><tr><td class="line">575</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">576</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">577</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">578</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">579</td><td class="hits"></td><td class="source"> * 插入多条数据</td></tr><tr><td class="line">580</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">581</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">582</td><td class="hits"></td><td class="source"> * @param {[type]} replace [description]</td></tr><tr><td class="line">583</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">584</td><td class="hits"></td><td class="source"> addAll: function(data, options, replace){</td></tr><tr class="miss"><td class="line">585</td><td class="hits">0</td><td class="source"> if (!isArray(data) || !isObject(data[0])) {</td></tr><tr class="miss"><td class="line">586</td><td class="hits">0</td><td class="source"> return getPromise(L('_DATA_TYPE_INVALID_'), true);</td></tr><tr><td class="line">587</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">588</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">589</td><td class="hits">0</td><td class="source"> return this.parseOptions(options).then(function(options){</td></tr><tr class="miss"><td class="line">590</td><td class="hits">0</td><td class="source"> return self.db.insertAll(data, options, replace);</td></tr><tr><td class="line">591</td><td class="hits"></td><td class="source"> }).then(function(){</td></tr><tr class="miss"><td class="line">592</td><td class="hits">0</td><td class="source"> return self.db.getLastInsertId();</td></tr><tr><td class="line">593</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">594</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">595</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">596</td><td class="hits"></td><td class="source"> * 删除后续操作</td></tr><tr><td class="line">597</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">598</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">599</td><td class="hits"></td><td class="source"> _afterDelete: function(data){</td></tr><tr class="miss"><td class="line">600</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">601</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">602</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">603</td><td class="hits"></td><td class="source"> * 删除数据</td></tr><tr><td class="line">604</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">605</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">606</td><td class="hits"></td><td class="source"> delete: function(options){</td></tr><tr class="miss"><td class="line">607</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">608</td><td class="hits">0</td><td class="source"> var parsedOptions = {};</td></tr><tr class="miss"><td class="line">609</td><td class="hits">0</td><td class="source"> var affectedRows = 0;</td></tr><tr class="miss"><td class="line">610</td><td class="hits">0</td><td class="source"> return this.parseOptions(options).then(function(options){</td></tr><tr class="miss"><td class="line">611</td><td class="hits">0</td><td class="source"> parsedOptions = options;</td></tr><tr class="miss"><td class="line">612</td><td class="hits">0</td><td class="source"> return self.db.delete(options);</td></tr><tr><td class="line">613</td><td class="hits"></td><td class="source"> }).then(function(rows){</td></tr><tr class="miss"><td class="line">614</td><td class="hits">0</td><td class="source"> affectedRows = rows;</td></tr><tr class="miss"><td class="line">615</td><td class="hits">0</td><td class="source"> return self._afterDelete(parsedOptions.where || {}, parsedOptions);</td></tr><tr><td class="line">616</td><td class="hits"></td><td class="source"> }).then(function(){</td></tr><tr class="miss"><td class="line">617</td><td class="hits">0</td><td class="source"> return affectedRows;</td></tr><tr><td class="line">618</td><td class="hits"></td><td class="source"> })</td></tr><tr><td class="line">619</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">620</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">621</td><td class="hits"></td><td class="source"> * 更新前置操作</td></tr><tr><td class="line">622</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">623</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">624</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">625</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">626</td><td class="hits"></td><td class="source"> _beforeUpdate: function(data){</td></tr><tr class="miss"><td class="line">627</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">628</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">629</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">630</td><td class="hits"></td><td class="source"> * 更新后置操作</td></tr><tr><td class="line">631</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">632</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">633</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">634</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">635</td><td class="hits"></td><td class="source"> _afterUpdate: function(data){</td></tr><tr class="miss"><td class="line">636</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">637</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">638</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">639</td><td class="hits"></td><td class="source"> * 更新数据</td></tr><tr><td class="line">640</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">641</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">642</td><td class="hits"></td><td class="source"> update: function(data, options){</td></tr><tr class="miss"><td class="line">643</td><td class="hits">0</td><td class="source"> data = extend({}, data);</td></tr><tr class="miss"><td class="line">644</td><td class="hits">0</td><td class="source"> if (isEmpty(data)) {</td></tr><tr class="miss"><td class="line">645</td><td class="hits">0</td><td class="source"> if (this._data) {</td></tr><tr class="miss"><td class="line">646</td><td class="hits">0</td><td class="source"> data = this._data;</td></tr><tr class="miss"><td class="line">647</td><td class="hits">0</td><td class="source"> this._data = {};</td></tr><tr><td class="line">648</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">649</td><td class="hits">0</td><td class="source"> return getPromise(L('_DATA_TYPE_INVALID_'), true);</td></tr><tr><td class="line">650</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">651</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">652</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">653</td><td class="hits">0</td><td class="source"> var pk = self.getPk();</td></tr><tr class="miss"><td class="line">654</td><td class="hits">0</td><td class="source"> var parsedOptions = {};</td></tr><tr class="miss"><td class="line">655</td><td class="hits">0</td><td class="source"> var parsedData = {};</td></tr><tr class="miss"><td class="line">656</td><td class="hits">0</td><td class="source"> var affectedRows = 0;</td></tr><tr class="miss"><td class="line">657</td><td class="hits">0</td><td class="source"> return this.parseOptions(options).then(function(options){</td></tr><tr class="miss"><td class="line">658</td><td class="hits">0</td><td class="source"> parsedOptions = options;</td></tr><tr class="miss"><td class="line">659</td><td class="hits">0</td><td class="source"> return self._beforeUpdate(data, options);</td></tr><tr><td class="line">660</td><td class="hits"></td><td class="source"> }).then(function(data){</td></tr><tr class="miss"><td class="line">661</td><td class="hits">0</td><td class="source"> parsedData = data;</td></tr><tr class="miss"><td class="line">662</td><td class="hits">0</td><td class="source"> data = self.parseData(data);</td></tr><tr class="miss"><td class="line">663</td><td class="hits">0</td><td class="source"> if (isEmpty(parsedOptions.where)) {</td></tr><tr><td class="line">664</td><td class="hits"></td><td class="source"> // 如果存在主键数据 则自动作为更新条件</td></tr><tr class="miss"><td class="line">665</td><td class="hits">0</td><td class="source"> if (!isEmpty(data[pk])) {</td></tr><tr class="miss"><td class="line">666</td><td class="hits">0</td><td class="source"> parsedOptions.where = getObject(pk, data[pk]);</td></tr><tr class="miss"><td class="line">667</td><td class="hits">0</td><td class="source"> delete data[pk];</td></tr><tr><td class="line">668</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">669</td><td class="hits">0</td><td class="source"> return getPromise(L('_OPERATION_WRONG_'), true);</td></tr><tr><td class="line">670</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">671</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">672</td><td class="hits">0</td><td class="source"> parsedData[pk] = parsedOptions.where[pk];</td></tr><tr><td class="line">673</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">674</td><td class="hits">0</td><td class="source"> return self.db.update(data, parsedOptions);</td></tr><tr><td class="line">675</td><td class="hits"></td><td class="source"> }).then(function(rows){</td></tr><tr class="miss"><td class="line">676</td><td class="hits">0</td><td class="source"> affectedRows = rows;</td></tr><tr class="miss"><td class="line">677</td><td class="hits">0</td><td class="source"> return self._afterUpdate(parsedData, parsedOptions);</td></tr><tr><td class="line">678</td><td class="hits"></td><td class="source"> }).then(function(){</td></tr><tr class="miss"><td class="line">679</td><td class="hits">0</td><td class="source"> return affectedRows;</td></tr><tr><td class="line">680</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">681</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">682</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">683</td><td class="hits"></td><td class="source"> * 更新多个数据,自动用主键作为查询条件</td></tr><tr><td class="line">684</td><td class="hits"></td><td class="source"> * @param {[type]} dataList [description]</td></tr><tr><td class="line">685</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">686</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">687</td><td class="hits"></td><td class="source"> updateAll: function(dataList){</td></tr><tr class="miss"><td class="line">688</td><td class="hits">0</td><td class="source"> if (!isArray(dataList) || !isObject(dataList[0])) {</td></tr><tr class="miss"><td class="line">689</td><td class="hits">0</td><td class="source"> return getPromise(L('_DATA_TYPE_INVALID_'), true);</td></tr><tr><td class="line">690</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">691</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">692</td><td class="hits">0</td><td class="source"> var promises = dataList.map(function(data){</td></tr><tr class="miss"><td class="line">693</td><td class="hits">0</td><td class="source"> return self.update(data);</td></tr><tr><td class="line">694</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">695</td><td class="hits">0</td><td class="source"> return Promise.all(promises);</td></tr><tr><td class="line">696</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">697</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">698</td><td class="hits"></td><td class="source"> * 更新某个字段的值</td></tr><tr><td class="line">699</td><td class="hits"></td><td class="source"> * @param {[type]} field [description]</td></tr><tr><td class="line">700</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">701</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">702</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">703</td><td class="hits"></td><td class="source"> updateField: function(field, value){</td></tr><tr class="miss"><td class="line">704</td><td class="hits">0</td><td class="source"> var data = {};</td></tr><tr class="miss"><td class="line">705</td><td class="hits">0</td><td class="source"> if (isObject(field)) {</td></tr><tr class="miss"><td class="line">706</td><td class="hits">0</td><td class="source"> data = field;</td></tr><tr><td class="line">707</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">708</td><td class="hits">0</td><td class="source"> data[field] = value;</td></tr><tr><td class="line">709</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">710</td><td class="hits">0</td><td class="source"> return this.update(data);</td></tr><tr><td class="line">711</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">712</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">713</td><td class="hits"></td><td class="source"> * 字段值增长</td></tr><tr><td class="line">714</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">715</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">716</td><td class="hits"></td><td class="source"> updateInc: function(field, step){</td></tr><tr class="miss"><td class="line">717</td><td class="hits">0</td><td class="source"> step = parseInt(step, 10) || 1;</td></tr><tr class="miss"><td class="line">718</td><td class="hits">0</td><td class="source"> return this.updateField(field, ['exp', field + '+' + step]);</td></tr><tr><td class="line">719</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">720</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">721</td><td class="hits"></td><td class="source"> * 字段值减少</td></tr><tr><td class="line">722</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">723</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">724</td><td class="hits"></td><td class="source"> updateDec: function(field, step){</td></tr><tr class="miss"><td class="line">725</td><td class="hits">0</td><td class="source"> step = parseInt(step, 10) || 1;</td></tr><tr class="miss"><td class="line">726</td><td class="hits">0</td><td class="source"> return this.updateField(field, ['exp', field + '-' + step]);</td></tr><tr><td class="line">727</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">728</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">729</td><td class="hits"></td><td class="source"> * 解析options中简洁的where条件</td></tr><tr><td class="line">730</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">731</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">732</td><td class="hits"></td><td class="source"> parseWhereOptions: function(options){</td></tr><tr class="miss"><td class="line">733</td><td class="hits">0</td><td class="source"> if (isNumber(options) || isString(options)) {</td></tr><tr class="miss"><td class="line">734</td><td class="hits">0</td><td class="source"> var pk = this.getPk();</td></tr><tr class="miss"><td class="line">735</td><td class="hits">0</td><td class="source"> options += '';</td></tr><tr class="miss"><td class="line">736</td><td class="hits">0</td><td class="source"> var where = {};</td></tr><tr class="miss"><td class="line">737</td><td class="hits">0</td><td class="source"> if (options.indexOf(',') &gt; -1) {</td></tr><tr class="miss"><td class="line">738</td><td class="hits">0</td><td class="source"> where[pk] = ['IN', options];</td></tr><tr><td class="line">739</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">740</td><td class="hits">0</td><td class="source"> where[pk] = options;</td></tr><tr><td class="line">741</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">742</td><td class="hits">0</td><td class="source"> options = {</td></tr><tr><td class="line">743</td><td class="hits"></td><td class="source"> where: where</td></tr><tr><td class="line">744</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">745</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">746</td><td class="hits">0</td><td class="source"> return options || {};</td></tr><tr><td class="line">747</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">748</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">749</td><td class="hits"></td><td class="source"> * find查询后置操作</td></tr><tr><td class="line">750</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">751</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">752</td><td class="hits"></td><td class="source"> _afterFind: function(result){</td></tr><tr class="miss"><td class="line">753</td><td class="hits">0</td><td class="source"> return result;</td></tr><tr><td class="line">754</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">755</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">756</td><td class="hits"></td><td class="source"> * 查询一条数据</td></tr><tr><td class="line">757</td><td class="hits"></td><td class="source"> * @return 返回一个promise</td></tr><tr><td class="line">758</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">759</td><td class="hits"></td><td class="source"> find: function(options){</td></tr><tr class="miss"><td class="line">760</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">761</td><td class="hits">0</td><td class="source"> var parsedOptions = {};</td></tr><tr class="miss"><td class="line">762</td><td class="hits">0</td><td class="source"> return this.parseOptions(options, {</td></tr><tr><td class="line">763</td><td class="hits"></td><td class="source"> limit: 1</td></tr><tr><td class="line">764</td><td class="hits"></td><td class="source"> }).then(function(options){</td></tr><tr class="miss"><td class="line">765</td><td class="hits">0</td><td class="source"> parsedOptions = options;</td></tr><tr class="miss"><td class="line">766</td><td class="hits">0</td><td class="source"> return self.db.select(options);</td></tr><tr><td class="line">767</td><td class="hits"></td><td class="source"> }).then(function(data){</td></tr><tr class="miss"><td class="line">768</td><td class="hits">0</td><td class="source"> return self._afterFind(data[0] || {}, parsedOptions);</td></tr><tr><td class="line">769</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">770</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">771</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">772</td><td class="hits"></td><td class="source"> * 查询后置操作</td></tr><tr><td class="line">773</td><td class="hits"></td><td class="source"> * @param {[type]} result [description]</td></tr><tr><td class="line">774</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">775</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">776</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">777</td><td class="hits"></td><td class="source"> _afterSelect: function(result){</td></tr><tr class="miss"><td class="line">778</td><td class="hits">0</td><td class="source"> return result;</td></tr><tr><td class="line">779</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">780</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">781</td><td class="hits"></td><td class="source"> * 查询数据</td></tr><tr><td class="line">782</td><td class="hits"></td><td class="source"> * @return 返回一个promise</td></tr><tr><td class="line">783</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">784</td><td class="hits"></td><td class="source"> select: function(options){</td></tr><tr class="miss"><td class="line">785</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">786</td><td class="hits">0</td><td class="source"> var parsedOptions = {};</td></tr><tr class="miss"><td class="line">787</td><td class="hits">0</td><td class="source"> return this.parseOptions(options).then(function(options){</td></tr><tr class="miss"><td class="line">788</td><td class="hits">0</td><td class="source"> parsedOptions = options;</td></tr><tr class="miss"><td class="line">789</td><td class="hits">0</td><td class="source"> return self.db.select(options);</td></tr><tr><td class="line">790</td><td class="hits"></td><td class="source"> }).then(function(result){</td></tr><tr class="miss"><td class="line">791</td><td class="hits">0</td><td class="source"> return self._afterSelect(result, parsedOptions);</td></tr><tr><td class="line">792</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">793</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">794</td><td class="hits"></td><td class="source"> selectAdd: function(fields, table, options){</td></tr><tr class="miss"><td class="line">795</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">796</td><td class="hits">0</td><td class="source"> return this.parseOptions(options).then(function(options){</td></tr><tr class="miss"><td class="line">797</td><td class="hits">0</td><td class="source"> fields = fields || options.field;</td></tr><tr class="miss"><td class="line">798</td><td class="hits">0</td><td class="source"> table = table || self.getTableName();</td></tr><tr class="miss"><td class="line">799</td><td class="hits">0</td><td class="source"> return self.db.selectInsert(fields, table, options);</td></tr><tr><td class="line">800</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">801</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">802</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">803</td><td class="hits"></td><td class="source"> * 返回数据里含有count信息的查询</td></tr><tr><td class="line">804</td><td class="hits"></td><td class="source"> * @param options 查询选项</td></tr><tr><td class="line">805</td><td class="hits"></td><td class="source"> * @param pageFlag 当页面不合法时的处理方式true为获取第一页false为获取最后一页undefined获取为空</td></tr><tr><td class="line">806</td><td class="hits"></td><td class="source"> * @return promise </td></tr><tr><td class="line">807</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">808</td><td class="hits"></td><td class="source"> countSelect: function(options, pageFlag){</td></tr><tr class="miss"><td class="line">809</td><td class="hits">0</td><td class="source"> if (isBoolean(options)) {</td></tr><tr class="miss"><td class="line">810</td><td class="hits">0</td><td class="source"> pageFlag = options;</td></tr><tr class="miss"><td class="line">811</td><td class="hits">0</td><td class="source"> options = {};</td></tr><tr><td class="line">812</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">813</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr><td class="line">814</td><td class="hits"></td><td class="source"> //解析后的options</td></tr><tr class="miss"><td class="line">815</td><td class="hits">0</td><td class="source"> var parsedOptions = {};</td></tr><tr class="miss"><td class="line">816</td><td class="hits">0</td><td class="source"> var result = {};</td></tr><tr class="miss"><td class="line">817</td><td class="hits">0</td><td class="source"> return this.parseOptions(options).then(function(options){</td></tr><tr class="miss"><td class="line">818</td><td class="hits">0</td><td class="source"> delete options.table;</td></tr><tr class="miss"><td class="line">819</td><td class="hits">0</td><td class="source"> parsedOptions = options;</td></tr><tr class="miss"><td class="line">820</td><td class="hits">0</td><td class="source"> return self.options({</td></tr><tr><td class="line">821</td><td class="hits"></td><td class="source"> where: options.where,</td></tr><tr><td class="line">822</td><td class="hits"></td><td class="source"> cache: options.cache,</td></tr><tr><td class="line">823</td><td class="hits"></td><td class="source"> join: options.join</td></tr><tr><td class="line">824</td><td class="hits"></td><td class="source"> }).count(self.getTableName() + '.' + self.getPk());</td></tr><tr><td class="line">825</td><td class="hits"></td><td class="source"> }).then(function(count){</td></tr><tr class="miss"><td class="line">826</td><td class="hits">0</td><td class="source"> var pageOptions = parsePage(parsedOptions);</td></tr><tr class="miss"><td class="line">827</td><td class="hits">0</td><td class="source"> var totalPage = Math.ceil(count / pageOptions.num);</td></tr><tr class="miss"><td class="line">828</td><td class="hits">0</td><td class="source"> if (isBoolean(pageFlag)) {</td></tr><tr class="miss"><td class="line">829</td><td class="hits">0</td><td class="source"> if (pageOptions.page &gt; totalPage) {</td></tr><tr class="miss"><td class="line">830</td><td class="hits">0</td><td class="source"> pageOptions.page = pageFlag === true ? 1 : totalPage;</td></tr><tr><td class="line">831</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">832</td><td class="hits">0</td><td class="source"> parsedOptions.page = pageOptions.page + ',' + pageOptions.num;</td></tr><tr><td class="line">833</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">834</td><td class="hits">0</td><td class="source"> result = extend({count: count, total: totalPage}, pageOptions);</td></tr><tr class="miss"><td class="line">835</td><td class="hits">0</td><td class="source"> return self.select(parsedOptions);</td></tr><tr><td class="line">836</td><td class="hits"></td><td class="source"> }).then(function(data){</td></tr><tr class="miss"><td class="line">837</td><td class="hits">0</td><td class="source"> result.data = data;</td></tr><tr class="miss"><td class="line">838</td><td class="hits">0</td><td class="source"> return result;</td></tr><tr><td class="line">839</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">840</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">841</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">842</td><td class="hits"></td><td class="source"> * 获取一条记录的某个字段值</td></tr><tr><td class="line">843</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">844</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">845</td><td class="hits"></td><td class="source"> getField: function(field, sepa){</td></tr><tr class="miss"><td class="line">846</td><td class="hits">0</td><td class="source"> field = field.trim();</td></tr><tr class="miss"><td class="line">847</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">848</td><td class="hits">0</td><td class="source"> var multi = false;</td></tr><tr class="miss"><td class="line">849</td><td class="hits">0</td><td class="source"> var parseOptions;</td></tr><tr class="miss"><td class="line">850</td><td class="hits">0</td><td class="source"> return this.parseOptions({</td></tr><tr><td class="line">851</td><td class="hits"></td><td class="source"> 'field': field</td></tr><tr><td class="line">852</td><td class="hits"></td><td class="source"> }).then(function(options){</td></tr><tr class="miss"><td class="line">853</td><td class="hits">0</td><td class="source"> parseOptions = options;</td></tr><tr class="miss"><td class="line">854</td><td class="hits">0</td><td class="source"> if (field.indexOf(',') &gt; -1) {</td></tr><tr class="miss"><td class="line">855</td><td class="hits">0</td><td class="source"> if (options.limit === undefined &amp;&amp; isNumber(sepa)) {</td></tr><tr class="miss"><td class="line">856</td><td class="hits">0</td><td class="source"> options.limit = sepa;</td></tr><tr><td class="line">857</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">858</td><td class="hits">0</td><td class="source"> multi = true;</td></tr><tr><td class="line">859</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">860</td><td class="hits">0</td><td class="source"> options.limit = isNumber(sepa) ? sepa : 1; </td></tr><tr><td class="line">861</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">862</td><td class="hits">0</td><td class="source"> return self.db.select(options);</td></tr><tr><td class="line">863</td><td class="hits"></td><td class="source"> }).then(function(data){</td></tr><tr class="miss"><td class="line">864</td><td class="hits">0</td><td class="source"> if (multi) {</td></tr><tr class="miss"><td class="line">865</td><td class="hits">0</td><td class="source"> var length = field.split(',').length;</td></tr><tr class="miss"><td class="line">866</td><td class="hits">0</td><td class="source"> field = Object.keys(data[0] || {});</td></tr><tr class="miss"><td class="line">867</td><td class="hits">0</td><td class="source"> var key = field.shift();</td></tr><tr class="miss"><td class="line">868</td><td class="hits">0</td><td class="source"> var key2 = field.shift();</td></tr><tr class="miss"><td class="line">869</td><td class="hits">0</td><td class="source"> var cols = {};</td></tr><tr class="miss"><td class="line">870</td><td class="hits">0</td><td class="source"> data.forEach(function(item){</td></tr><tr class="miss"><td class="line">871</td><td class="hits">0</td><td class="source"> var name = item[key];</td></tr><tr class="miss"><td class="line">872</td><td class="hits">0</td><td class="source"> if (length === 2) {</td></tr><tr class="miss"><td class="line">873</td><td class="hits">0</td><td class="source"> cols[name] = item[key2];</td></tr><tr><td class="line">874</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">875</td><td class="hits">0</td><td class="source"> cols[name] = isString(sepa) ? item.join(sepa) : item;</td></tr><tr><td class="line">876</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">877</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">878</td><td class="hits">0</td><td class="source"> return cols;</td></tr><tr><td class="line">879</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">880</td><td class="hits">0</td><td class="source"> if (sepa !== true &amp;&amp; parseOptions.limit === 1) {</td></tr><tr class="miss"><td class="line">881</td><td class="hits">0</td><td class="source"> return data[0];</td></tr><tr><td class="line">882</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">883</td><td class="hits">0</td><td class="source"> return Object.values(data[0] || {})[0];</td></tr><tr><td class="line">884</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">885</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">886</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">887</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">888</td><td class="hits"></td><td class="source"> * 根据某个字段值获取一条数据</td></tr><tr><td class="line">889</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">890</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">891</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">892</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">893</td><td class="hits"></td><td class="source"> getBy: function(name, value){</td></tr><tr class="miss"><td class="line">894</td><td class="hits">0</td><td class="source"> var where = getObject(name, value);</td></tr><tr class="miss"><td class="line">895</td><td class="hits">0</td><td class="source"> return this.where(where).find();</td></tr><tr><td class="line">896</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">897</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">898</td><td class="hits"></td><td class="source"> * SQL查询</td></tr><tr><td class="line">899</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">900</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">901</td><td class="hits"></td><td class="source"> query: function(sql, parse){</td></tr><tr class="miss"><td class="line">902</td><td class="hits">0</td><td class="source"> if (parse !== undefined &amp;&amp; !isBoolean(parse) &amp;&amp; !isArray(parse)) {</td></tr><tr class="miss"><td class="line">903</td><td class="hits">0</td><td class="source"> parse = [].slice.call(arguments);</td></tr><tr class="miss"><td class="line">904</td><td class="hits">0</td><td class="source"> parse.shift();</td></tr><tr><td class="line">905</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">906</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">907</td><td class="hits">0</td><td class="source"> return this.parseSql(sql, parse).then(function(sql){</td></tr><tr class="miss"><td class="line">908</td><td class="hits">0</td><td class="source"> return self.db.query(sql);</td></tr><tr><td class="line">909</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">910</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">911</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">912</td><td class="hits"></td><td class="source"> * 执行SQL语法非查询类的SQL语句返回值为影响的行数</td></tr><tr><td class="line">913</td><td class="hits"></td><td class="source"> * @param {[type]} sql [description]</td></tr><tr><td class="line">914</td><td class="hits"></td><td class="source"> * @param {[type]} parse [description]</td></tr><tr><td class="line">915</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">916</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">917</td><td class="hits"></td><td class="source"> execute: function(sql, parse){</td></tr><tr class="miss"><td class="line">918</td><td class="hits">0</td><td class="source"> if (parse !== undefined &amp;&amp; !isBoolean(parse) &amp;&amp; !isArray(parse)) {</td></tr><tr class="miss"><td class="line">919</td><td class="hits">0</td><td class="source"> parse = [].slice.call(arguments);</td></tr><tr class="miss"><td class="line">920</td><td class="hits">0</td><td class="source"> parse.shift();</td></tr><tr><td class="line">921</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">922</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">923</td><td class="hits">0</td><td class="source"> return this.parseSql(sql, parse).then(function(sql){</td></tr><tr class="miss"><td class="line">924</td><td class="hits">0</td><td class="source"> return self.db.execute(sql);</td></tr><tr><td class="line">925</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">926</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">927</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">928</td><td class="hits"></td><td class="source"> * 解析SQL语句</td></tr><tr><td class="line">929</td><td class="hits"></td><td class="source"> * @return promise [description]</td></tr><tr><td class="line">930</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">931</td><td class="hits"></td><td class="source"> parseSql: function(sql, parse){</td></tr><tr class="miss"><td class="line">932</td><td class="hits">0</td><td class="source"> var promise = null;</td></tr><tr class="miss"><td class="line">933</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">934</td><td class="hits">0</td><td class="source"> if (parse === true) {</td></tr><tr class="miss"><td class="line">935</td><td class="hits">0</td><td class="source"> promise = this.parseOptions().then(function(options){</td></tr><tr class="miss"><td class="line">936</td><td class="hits">0</td><td class="source"> return self.db.parseSql(options);</td></tr><tr><td class="line">937</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">938</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">939</td><td class="hits">0</td><td class="source"> if (parse === undefined) {</td></tr><tr class="miss"><td class="line">940</td><td class="hits">0</td><td class="source"> parse = [];</td></tr><tr><td class="line">941</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">942</td><td class="hits">0</td><td class="source"> parse = isArray(parse) ? parse : [parse];</td></tr><tr><td class="line">943</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">944</td><td class="hits">0</td><td class="source"> parse.unshift(sql);</td></tr><tr class="miss"><td class="line">945</td><td class="hits">0</td><td class="source"> sql = util.format.apply(null, parse);</td></tr><tr class="miss"><td class="line">946</td><td class="hits">0</td><td class="source"> var map = {</td></tr><tr><td class="line">947</td><td class="hits"></td><td class="source"> '__TABLE__': '`' + this.getTableName() + '`'</td></tr><tr><td class="line">948</td><td class="hits"></td><td class="source"> };</td></tr><tr class="miss"><td class="line">949</td><td class="hits">0</td><td class="source"> sql = sql.replace(/__([A-Z]+)__/g, function(a, b){</td></tr><tr class="miss"><td class="line">950</td><td class="hits">0</td><td class="source"> return map[a] || ('`' + C('db_prefix') + b.toLowerCase() + '`');</td></tr><tr><td class="line">951</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">952</td><td class="hits">0</td><td class="source"> promise = getPromise(sql);</td></tr><tr><td class="line">953</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">954</td><td class="hits">0</td><td class="source"> this.initDb().setModel(self.name);</td></tr><tr class="miss"><td class="line">955</td><td class="hits">0</td><td class="source"> return promise;</td></tr><tr><td class="line">956</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">957</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">958</td><td class="hits"></td><td class="source"> * 设置数据对象值</td></tr><tr><td class="line">959</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">960</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">961</td><td class="hits"></td><td class="source"> data: function(data){</td></tr><tr class="miss"><td class="line">962</td><td class="hits">0</td><td class="source"> if (data === true) {</td></tr><tr class="miss"><td class="line">963</td><td class="hits">0</td><td class="source"> return this._data;</td></tr><tr><td class="line">964</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">965</td><td class="hits">0</td><td class="source"> if (isString(data)) {</td></tr><tr class="miss"><td class="line">966</td><td class="hits">0</td><td class="source"> data = querystring.parse(data);</td></tr><tr><td class="line">967</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">968</td><td class="hits">0</td><td class="source"> this._data = data;</td></tr><tr class="miss"><td class="line">969</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">970</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">971</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">972</td><td class="hits"></td><td class="source"> * 设置操作选项</td></tr><tr><td class="line">973</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">974</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">975</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">976</td><td class="hits"></td><td class="source"> options: function(options){</td></tr><tr class="miss"><td class="line">977</td><td class="hits">0</td><td class="source"> if (options === true) {</td></tr><tr class="miss"><td class="line">978</td><td class="hits">0</td><td class="source"> return this._options;</td></tr><tr><td class="line">979</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">980</td><td class="hits">0</td><td class="source"> this._options = options;</td></tr><tr class="miss"><td class="line">981</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">982</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">983</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">984</td><td class="hits"></td><td class="source"> * 关闭数据库连接</td></tr><tr><td class="line">985</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">986</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">987</td><td class="hits"></td><td class="source"> close: function(){</td></tr><tr class="miss"><td class="line">988</td><td class="hits">0</td><td class="source"> delete dbInstances[this.configKey];</td></tr><tr class="miss"><td class="line">989</td><td class="hits">0</td><td class="source"> if (this.db) {</td></tr><tr class="miss"><td class="line">990</td><td class="hits">0</td><td class="source"> this.db.close();</td></tr><tr><td class="line">991</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">992</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">993</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">994</td><td class="hits"></td><td class="source">}).extend(function(){</td></tr><tr class="hit"><td class="line">995</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr><td class="line">996</td><td class="hits"></td><td class="source"> //追加的方法</td></tr><tr class="hit"><td class="line">997</td><td class="hits">1</td><td class="source"> var methods = {};</td></tr><tr><td class="line">998</td><td class="hits"></td><td class="source"> // 链操作方法列表</td></tr><tr class="hit"><td class="line">999</td><td class="hits">1</td><td class="source"> var methodNameList = [</td></tr><tr><td class="line">1000</td><td class="hits"></td><td class="source"> 'table','order','alias','having','group',</td></tr><tr><td class="line">1001</td><td class="hits"></td><td class="source"> 'lock','auto','filter','validate'</td></tr><tr><td class="line">1002</td><td class="hits"></td><td class="source"> ];</td></tr><tr class="hit"><td class="line">1003</td><td class="hits">1</td><td class="source"> methodNameList.forEach(function(item){</td></tr><tr class="hit"><td class="line">1004</td><td class="hits">9</td><td class="source"> methods[item] = function(data){</td></tr><tr class="miss"><td class="line">1005</td><td class="hits">0</td><td class="source"> this._options[item] = data;</td></tr><tr class="miss"><td class="line">1006</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">1007</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">1008</td><td class="hits"></td><td class="source"> });</td></tr><tr class="hit"><td class="line">1009</td><td class="hits">1</td><td class="source"> methods.distinct = function(data){</td></tr><tr class="miss"><td class="line">1010</td><td class="hits">0</td><td class="source"> this._options.distinct = data;</td></tr><tr><td class="line">1011</td><td class="hits"></td><td class="source"> //如果传过来一个字段则映射到field上</td></tr><tr class="miss"><td class="line">1012</td><td class="hits">0</td><td class="source"> if (isString(data)) {</td></tr><tr class="miss"><td class="line">1013</td><td class="hits">0</td><td class="source"> this._options.field = data;</td></tr><tr><td class="line">1014</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">1015</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">1016</td><td class="hits"></td><td class="source"> };</td></tr><tr class="hit"><td class="line">1017</td><td class="hits">1</td><td class="source"> ['count','sum','min','max','avg'].forEach(function(item){</td></tr><tr class="hit"><td class="line">1018</td><td class="hits">5</td><td class="source"> methods[item] = function(data){</td></tr><tr class="miss"><td class="line">1019</td><td class="hits">0</td><td class="source"> var field = data || '*';</td></tr><tr class="miss"><td class="line">1020</td><td class="hits">0</td><td class="source"> return this.getField(item.toUpperCase() + '(' + field + ') AS thinkjs_' + item, true);</td></tr><tr><td class="line">1021</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">1022</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">1023</td><td class="hits"></td><td class="source"> //方法别名</td></tr><tr class="hit"><td class="line">1024</td><td class="hits">1</td><td class="source"> var aliasMethodMap = {</td></tr><tr><td class="line">1025</td><td class="hits"></td><td class="source"> update: 'save',</td></tr><tr><td class="line">1026</td><td class="hits"></td><td class="source"> updateField: 'setField',</td></tr><tr><td class="line">1027</td><td class="hits"></td><td class="source"> updateInc: 'setInc',</td></tr><tr><td class="line">1028</td><td class="hits"></td><td class="source"> updateDec: 'setDec'</td></tr><tr><td class="line">1029</td><td class="hits"></td><td class="source"> };</td></tr><tr class="hit"><td class="line">1030</td><td class="hits">1</td><td class="source"> Object.keys(aliasMethodMap).forEach(function(key){</td></tr><tr class="hit"><td class="line">1031</td><td class="hits">4</td><td class="source"> var value = aliasMethodMap[key];</td></tr><tr class="hit"><td class="line">1032</td><td class="hits">4</td><td class="source"> methods[value] = function(){</td></tr><tr class="miss"><td class="line">1033</td><td class="hits">0</td><td class="source"> return this[key].apply(this, arguments);</td></tr><tr><td class="line">1034</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">1035</td><td class="hits"></td><td class="source"> });</td></tr><tr class="hit"><td class="line">1036</td><td class="hits">1</td><td class="source"> return methods;</td></tr><tr><td class="line">1037</td><td class="hits"></td><td class="source">});</td></tr><tr><td class="line">1038</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">1039</td><td class="hits"></td><td class="source"> * 关闭所有的数据库连接</td></tr><tr><td class="line">1040</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">1041</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">1042</td><td class="hits">1</td><td class="source">Model.close = global.closeDb = function(){</td></tr><tr class="miss"><td class="line">1043</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">1044</td><td class="hits">0</td><td class="source"> for(var key in dbInstances) {</td></tr><tr class="miss"><td class="line">1045</td><td class="hits">0</td><td class="source"> dbInstances[key].close();</td></tr><tr><td class="line">1046</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">1047</td><td class="hits"></td><td class="source"> </td></tr><tr class="miss"><td class="line">1048</td><td class="hits">0</td><td class="source"> dbInstances = {};</td></tr><tr><td class="line">1049</td><td class="hits"></td><td class="source">};</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Think.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/Think.js</h2><div id="stats" class="medium"><div class="percentage">56%</div><div class="sloc">147</div><div class="hits">83</div><div class="misses">64</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"><td class="line">1</td><td class="hits">1</td><td class="source">var fs = require('fs');</td></tr><tr class="hit"><td class="line">2</td><td class="hits">1</td><td class="source">var cluster = require('cluster');</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source">//自动加载进行识别的路径</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">var autoloadPaths = {};</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> * [exports description]</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> * @type {Object}</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">10</td><td class="hits">1</td><td class="source">module.exports = {</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> * [start description]</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> start: function(){</td></tr><tr class="hit"><td class="line">16</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">17</td><td class="hits">1</td><td class="source"> this.init();</td></tr><tr class="hit"><td class="line">18</td><td class="hits">1</td><td class="source"> this.processEvent();</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> //加载文件</td></tr><tr class="hit"><td class="line">20</td><td class="hits">1</td><td class="source"> this.loadFiles();</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> //合并自动加载的路径</td></tr><tr class="hit"><td class="line">22</td><td class="hits">1</td><td class="source"> this.mergeAutoloadPath();</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> //thinkRequire的autoload</td></tr><tr class="hit"><td class="line">24</td><td class="hits">1</td><td class="source"> registerAutoload(this.autoload);</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source"> //debug模式</td></tr><tr class="hit"><td class="line">26</td><td class="hits">1</td><td class="source"> if (APP_DEBUG) {</td></tr><tr class="miss"><td class="line">27</td><td class="hits">0</td><td class="source"> this.debug();</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> //记录进程的id</td></tr><tr class="hit"><td class="line">30</td><td class="hits">1</td><td class="source"> this.logPid();</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">32</td><td class="hits">1</td><td class="source"> thinkRequire('App').run();</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> * 定义一些目录,加载框架的基础文件</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> init: function(){</td></tr><tr class="hit"><td class="line">39</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> //系统路径设置</td></tr><tr class="hit"><td class="line">41</td><td class="hits">1</td><td class="source"> global.THINK_LIB_PATH = THINK_PATH + '/Lib';</td></tr><tr class="hit"><td class="line">42</td><td class="hits">1</td><td class="source"> global.THINK_EXTEND_PATH = THINK_LIB_PATH + '/Extend';</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> //应用路径设置</td></tr><tr class="hit"><td class="line">44</td><td class="hits">1</td><td class="source"> var config = {</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source"> COMMON_PATH: APP_PATH + '/Common',</td></tr><tr><td class="line">46</td><td class="hits"></td><td class="source"> LIB_PATH: APP_PATH + '/Lib',</td></tr><tr><td class="line">47</td><td class="hits"></td><td class="source"> CONF_PATH: APP_PATH + '/Conf',</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> LANG_PATH: APP_PATH + '/Lang',</td></tr><tr><td class="line">49</td><td class="hits"></td><td class="source"> VIEW_PATH: APP_PATH + '/View',</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> //HTML_PATH: RUNTIME_PATH + '/Html',</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> LOG_PATH: RUNTIME_PATH + '/Log',</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> TEMP_PATH: RUNTIME_PATH + '/Temp',</td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> DATA_PATH: RUNTIME_PATH + '/Data',</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> CACHE_PATH: RUNTIME_PATH + '/Cache'</td></tr><tr><td class="line">55</td><td class="hits"></td><td class="source"> };</td></tr><tr class="hit"><td class="line">56</td><td class="hits">1</td><td class="source"> for (var name in config) {</td></tr><tr class="hit"><td class="line">57</td><td class="hits">9</td><td class="source"> if (global[name] === undefined) {</td></tr><tr class="hit"><td class="line">58</td><td class="hits">9</td><td class="source"> global[name] = config[name];</td></tr><tr><td class="line">59</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">61</td><td class="hits">1</td><td class="source"> require(THINK_PATH + '/Common/extend.js');</td></tr><tr class="hit"><td class="line">62</td><td class="hits">1</td><td class="source"> require(THINK_PATH + '/Common/common.js');</td></tr><tr class="hit"><td class="line">63</td><td class="hits">1</td><td class="source"> require(THINK_PATH + '/Common/function.js');</td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> //别名导入</td></tr><tr class="hit"><td class="line">65</td><td class="hits">1</td><td class="source"> aliasImport(require(THINK_PATH + '/Conf/alias.js'));</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">68</td><td class="hits"></td><td class="source"> * 注册异常处理</td></tr><tr><td class="line">69</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">70</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">71</td><td class="hits"></td><td class="source"> processEvent: function(){</td></tr><tr class="hit"><td class="line">72</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">73</td><td class="hits">1</td><td class="source"> process.on('uncaughtException', function(err) {</td></tr><tr class="miss"><td class="line">74</td><td class="hits">0</td><td class="source"> console.log(isError(err) ? err.stack : err);</td></tr><tr><td class="line">75</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">76</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">77</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">78</td><td class="hits"></td><td class="source"> * 加载项目下对应的文件</td></tr><tr><td class="line">79</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">80</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">81</td><td class="hits"></td><td class="source"> loadFiles: function(){</td></tr><tr class="hit"><td class="line">82</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">83</td><td class="hits">1</td><td class="source"> C(null); //移除之前的所有配置</td></tr><tr><td class="line">84</td><td class="hits"></td><td class="source"> //加载系统默认配置</td></tr><tr class="hit"><td class="line">85</td><td class="hits">1</td><td class="source"> C(require(THINK_PATH + '/Conf/config.js'));</td></tr><tr><td class="line">86</td><td class="hits"></td><td class="source"> //加载用户配置</td></tr><tr class="hit"><td class="line">87</td><td class="hits">1</td><td class="source"> var file = CONF_PATH + '/config.js';</td></tr><tr class="hit"><td class="line">88</td><td class="hits">1</td><td class="source"> if (isFile(file)) {</td></tr><tr class="hit"><td class="line">89</td><td class="hits">1</td><td class="source"> C(require(file));</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">91</td><td class="hits"></td><td class="source"> //加载模式的配置文件</td></tr><tr class="hit"><td class="line">92</td><td class="hits">1</td><td class="source"> if (APP_MODE) {</td></tr><tr class="hit"><td class="line">93</td><td class="hits">1</td><td class="source"> var modeFiles = [</td></tr><tr><td class="line">94</td><td class="hits"></td><td class="source"> THINK_PATH + '/Conf/mode.js',</td></tr><tr><td class="line">95</td><td class="hits"></td><td class="source"> CONF_PATH + '/mode.js'</td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source"> ];</td></tr><tr class="hit"><td class="line">97</td><td class="hits">1</td><td class="source"> modeFiles.forEach(function(file){</td></tr><tr class="hit"><td class="line">98</td><td class="hits">2</td><td class="source"> if (isFile(file)) {</td></tr><tr class="hit"><td class="line">99</td><td class="hits">1</td><td class="source"> var conf = require(file);</td></tr><tr class="hit"><td class="line">100</td><td class="hits">1</td><td class="source"> if (conf[APP_MODE]) {</td></tr><tr class="hit"><td class="line">101</td><td class="hits">1</td><td class="source"> C(conf[APP_MODE]);</td></tr><tr><td class="line">102</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">103</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">104</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">105</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">106</td><td class="hits"></td><td class="source"> //自定义路由</td></tr><tr class="hit"><td class="line">107</td><td class="hits">1</td><td class="source"> if (C('url_route_on') &amp;&amp; isFile(CONF_PATH + '/route.js')) {</td></tr><tr class="miss"><td class="line">108</td><td class="hits">0</td><td class="source"> C('url_route_rules', require(CONF_PATH + '/route.js'));</td></tr><tr><td class="line">109</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">110</td><td class="hits"></td><td class="source"> //加载行为配置</td></tr><tr class="hit"><td class="line">111</td><td class="hits">1</td><td class="source"> if (C('app_tag_on')) {</td></tr><tr><td class="line">112</td><td class="hits"></td><td class="source"> //加载系统行为配置</td></tr><tr class="hit"><td class="line">113</td><td class="hits">1</td><td class="source"> C('sys_tag', require(THINK_PATH + '/Conf/tag.js'));</td></tr><tr><td class="line">114</td><td class="hits"></td><td class="source"> //加载用户的行为配置</td></tr><tr class="hit"><td class="line">115</td><td class="hits">1</td><td class="source"> var tagFile = CONF_PATH + '/tag.js';</td></tr><tr class="hit"><td class="line">116</td><td class="hits">1</td><td class="source"> if (isFile(tagFile)) {</td></tr><tr class="miss"><td class="line">117</td><td class="hits">0</td><td class="source"> C('tag', require(tagFile));</td></tr><tr><td class="line">118</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">119</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">120</td><td class="hits"></td><td class="source"> //common文件</td></tr><tr class="hit"><td class="line">121</td><td class="hits">1</td><td class="source"> if (isFile(COMMON_PATH + '/common.js')) {</td></tr><tr class="hit"><td class="line">122</td><td class="hits">1</td><td class="source"> require(COMMON_PATH + '/common.js');</td></tr><tr><td class="line">123</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">124</td><td class="hits"></td><td class="source"> //别名文件</td></tr><tr class="hit"><td class="line">125</td><td class="hits">1</td><td class="source"> if (isFile(COMMON_PATH + '/alias.js')) {</td></tr><tr class="miss"><td class="line">126</td><td class="hits">0</td><td class="source"> aliasImport(require(COMMON_PATH + '/alias.js'));</td></tr><tr><td class="line">127</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">128</td><td class="hits">1</td><td class="source"> this.loadExtConfig();</td></tr><tr class="hit"><td class="line">129</td><td class="hits">1</td><td class="source"> this.loadExtFiles();</td></tr><tr><td class="line">130</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">131</td><td class="hits"></td><td class="source"> //加载自定义外部文件</td></tr><tr><td class="line">132</td><td class="hits"></td><td class="source"> loadExtFiles: function(){</td></tr><tr class="hit"><td class="line">133</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">134</td><td class="hits">1</td><td class="source"> var files = C('load_ext_file');</td></tr><tr class="hit"><td class="line">135</td><td class="hits">1</td><td class="source"> if (files) {</td></tr><tr class="hit"><td class="line">136</td><td class="hits">1</td><td class="source"> if (isString(files)) {</td></tr><tr class="miss"><td class="line">137</td><td class="hits">0</td><td class="source"> files = files.split(',');</td></tr><tr><td class="line">138</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">139</td><td class="hits">1</td><td class="source"> files.forEach(function(file){</td></tr><tr class="miss"><td class="line">140</td><td class="hits">0</td><td class="source"> file = COMMON_PATH + '/' + file + '.js';</td></tr><tr class="miss"><td class="line">141</td><td class="hits">0</td><td class="source"> if (isFile(file)) {</td></tr><tr class="miss"><td class="line">142</td><td class="hits">0</td><td class="source"> require(file);</td></tr><tr><td class="line">143</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">144</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">145</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">146</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">147</td><td class="hits"></td><td class="source"> //加载额外的配置</td></tr><tr><td class="line">148</td><td class="hits"></td><td class="source"> loadExtConfig: function(){</td></tr><tr class="hit"><td class="line">149</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">150</td><td class="hits">1</td><td class="source"> var files = C('load_ext_config');</td></tr><tr class="hit"><td class="line">151</td><td class="hits">1</td><td class="source"> if (files) {</td></tr><tr class="hit"><td class="line">152</td><td class="hits">1</td><td class="source"> if (isString(files)) {</td></tr><tr class="miss"><td class="line">153</td><td class="hits">0</td><td class="source"> files = files.split(',');</td></tr><tr><td class="line">154</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">155</td><td class="hits">1</td><td class="source"> files.forEach(function(file){</td></tr><tr class="miss"><td class="line">156</td><td class="hits">0</td><td class="source"> file = CONF_PATH + '/' + file + '.js';</td></tr><tr class="miss"><td class="line">157</td><td class="hits">0</td><td class="source"> if (isFile(file)) {</td></tr><tr class="miss"><td class="line">158</td><td class="hits">0</td><td class="source"> C(require(file));</td></tr><tr><td class="line">159</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">160</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">161</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">162</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">163</td><td class="hits"></td><td class="source"> //加载debug模式配置文件</td></tr><tr><td class="line">164</td><td class="hits"></td><td class="source"> loadDebugFiles: function(){</td></tr><tr class="miss"><td class="line">165</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr><td class="line">166</td><td class="hits"></td><td class="source"> //加载debug模式下的配置</td></tr><tr class="miss"><td class="line">167</td><td class="hits">0</td><td class="source"> C(require(THINK_PATH + '/Conf/debug.js'));</td></tr><tr><td class="line">168</td><td class="hits"></td><td class="source"> //debug下自定义状态的配置</td></tr><tr class="miss"><td class="line">169</td><td class="hits">0</td><td class="source"> var status = C('app_status');</td></tr><tr class="miss"><td class="line">170</td><td class="hits">0</td><td class="source"> if (status) {</td></tr><tr class="miss"><td class="line">171</td><td class="hits">0</td><td class="source"> if (isFile(CONF_PATH + '/' + status + '.js')) {</td></tr><tr class="miss"><td class="line">172</td><td class="hits">0</td><td class="source"> C(require(CONF_PATH + '/' + status + '.js'));</td></tr><tr><td class="line">173</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">174</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">175</td><td class="hits">0</td><td class="source"> if (isFile(CONF_PATH + '/debug.js')) {</td></tr><tr class="miss"><td class="line">176</td><td class="hits">0</td><td class="source"> C(require(CONF_PATH + '/debug.js'));</td></tr><tr><td class="line">177</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">178</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">179</td><td class="hits">0</td><td class="source"> if (APP_MODE) {</td></tr><tr class="miss"><td class="line">180</td><td class="hits">0</td><td class="source"> var modeFiles = [</td></tr><tr><td class="line">181</td><td class="hits"></td><td class="source"> THINK_PATH + '/Conf/mode.js',</td></tr><tr><td class="line">182</td><td class="hits"></td><td class="source"> CONF_PATH + '/mode.js'</td></tr><tr><td class="line">183</td><td class="hits"></td><td class="source"> ];</td></tr><tr class="miss"><td class="line">184</td><td class="hits">0</td><td class="source"> modeFiles.forEach(function(file){</td></tr><tr class="miss"><td class="line">185</td><td class="hits">0</td><td class="source"> if (isFile(file)) {</td></tr><tr class="miss"><td class="line">186</td><td class="hits">0</td><td class="source"> var conf = require(file);</td></tr><tr class="miss"><td class="line">187</td><td class="hits">0</td><td class="source"> var key = APP_MODE + '_debug';</td></tr><tr class="miss"><td class="line">188</td><td class="hits">0</td><td class="source"> if (conf[key]) {</td></tr><tr class="miss"><td class="line">189</td><td class="hits">0</td><td class="source"> C(conf[key]);</td></tr><tr><td class="line">190</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">191</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">192</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">193</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">194</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">195</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">196</td><td class="hits"></td><td class="source"> * debug模式下一些特殊处理</td></tr><tr><td class="line">197</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">198</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">199</td><td class="hits"></td><td class="source"> debug: function(){</td></tr><tr class="miss"><td class="line">200</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">201</td><td class="hits">0</td><td class="source"> this.loadDebugFiles();</td></tr><tr><td class="line">202</td><td class="hits"></td><td class="source"> //清除require的缓存</td></tr><tr class="miss"><td class="line">203</td><td class="hits">0</td><td class="source"> if (C('clear_require_cache')) {</td></tr><tr><td class="line">204</td><td class="hits"></td><td class="source"> //这些文件不清除缓存</td></tr><tr class="miss"><td class="line">205</td><td class="hits">0</td><td class="source"> var retainFiles = C('debug_retain_files');</td></tr><tr class="miss"><td class="line">206</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">207</td><td class="hits">0</td><td class="source"> setInterval(function(){</td></tr><tr class="miss"><td class="line">208</td><td class="hits">0</td><td class="source"> var fn = function(item){</td></tr><tr><td class="line">209</td><td class="hits"></td><td class="source"> //windows目录定界符为\</td></tr><tr class="miss"><td class="line">210</td><td class="hits">0</td><td class="source"> if (process.platform === 'win32') {</td></tr><tr class="miss"><td class="line">211</td><td class="hits">0</td><td class="source"> item = item.replace(/\//g, '\\');</td></tr><tr><td class="line">212</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">213</td><td class="hits">0</td><td class="source"> if (file.indexOf(item) &gt; -1) {</td></tr><tr class="miss"><td class="line">214</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">215</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">216</td><td class="hits"></td><td class="source"> };</td></tr><tr class="miss"><td class="line">217</td><td class="hits">0</td><td class="source"> for(var file in require.cache){</td></tr><tr class="miss"><td class="line">218</td><td class="hits">0</td><td class="source"> var flag = retainFiles.some(fn);</td></tr><tr class="miss"><td class="line">219</td><td class="hits">0</td><td class="source"> if (!flag) {</td></tr><tr class="miss"><td class="line">220</td><td class="hits">0</td><td class="source"> delete require.cache[file];</td></tr><tr><td class="line">221</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">222</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">223</td><td class="hits">0</td><td class="source"> self.loadFiles();</td></tr><tr class="miss"><td class="line">224</td><td class="hits">0</td><td class="source"> self.loadDebugFiles();</td></tr><tr><td class="line">225</td><td class="hits"></td><td class="source"> }, 100);</td></tr><tr><td class="line">226</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">227</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">228</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">229</td><td class="hits"></td><td class="source"> * 记录当前进程的id</td></tr><tr><td class="line">230</td><td class="hits"></td><td class="source"> * 记录在Runtime/Data/app.pid文件里</td></tr><tr><td class="line">231</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">232</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">233</td><td class="hits"></td><td class="source"> logPid: function(){</td></tr><tr class="hit"><td class="line">234</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">235</td><td class="hits">1</td><td class="source"> if (C('log_process_pid') &amp;&amp; cluster.isMaster) {</td></tr><tr class="miss"><td class="line">236</td><td class="hits">0</td><td class="source"> mkdir(DATA_PATH);</td></tr><tr class="miss"><td class="line">237</td><td class="hits">0</td><td class="source"> var pidFile = DATA_PATH + '/app.pid';</td></tr><tr class="miss"><td class="line">238</td><td class="hits">0</td><td class="source"> fs.writeFileSync(pidFile, process.pid);</td></tr><tr class="miss"><td class="line">239</td><td class="hits">0</td><td class="source"> chmod(pidFile);</td></tr><tr><td class="line">240</td><td class="hits"></td><td class="source"> //进程退出时删除该文件</td></tr><tr class="miss"><td class="line">241</td><td class="hits">0</td><td class="source"> process.on('SIGTERM', function () {</td></tr><tr class="miss"><td class="line">242</td><td class="hits">0</td><td class="source"> if (fs.existsSync(pidFile)) {</td></tr><tr class="miss"><td class="line">243</td><td class="hits">0</td><td class="source"> fs.unlinkSync(pidFile);</td></tr><tr><td class="line">244</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">245</td><td class="hits">0</td><td class="source"> process.exit(0);</td></tr><tr><td class="line">246</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">247</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">248</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">249</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">250</td><td class="hits"></td><td class="source"> * 合并autoload的path</td></tr><tr><td class="line">251</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">252</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">253</td><td class="hits"></td><td class="source"> mergeAutoloadPath: function(){</td></tr><tr class="hit"><td class="line">254</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">255</td><td class="hits">1</td><td class="source"> var file = '__CLASS__.js';</td></tr><tr class="hit"><td class="line">256</td><td class="hits">1</td><td class="source"> var sysAutoloadPath = {</td></tr><tr><td class="line">257</td><td class="hits"></td><td class="source"> 'Behavior': [</td></tr><tr><td class="line">258</td><td class="hits"></td><td class="source"> LIB_PATH + '/Behavior/' + file,</td></tr><tr><td class="line">259</td><td class="hits"></td><td class="source"> THINK_LIB_PATH + '/Behavior/' + file</td></tr><tr><td class="line">260</td><td class="hits"></td><td class="source"> ],</td></tr><tr><td class="line">261</td><td class="hits"></td><td class="source"> 'Model': [</td></tr><tr><td class="line">262</td><td class="hits"></td><td class="source"> LIB_PATH + '/Model/' + file,</td></tr><tr><td class="line">263</td><td class="hits"></td><td class="source"> THINK_EXTEND_PATH + '/Model/' + file</td></tr><tr><td class="line">264</td><td class="hits"></td><td class="source"> ],</td></tr><tr><td class="line">265</td><td class="hits"></td><td class="source"> 'Controller': [</td></tr><tr><td class="line">266</td><td class="hits"></td><td class="source"> LIB_PATH + '/Controller/' + file,</td></tr><tr><td class="line">267</td><td class="hits"></td><td class="source"> THINK_EXTEND_PATH + '/Controller/' + file</td></tr><tr><td class="line">268</td><td class="hits"></td><td class="source"> ],</td></tr><tr><td class="line">269</td><td class="hits"></td><td class="source"> 'Cache': [</td></tr><tr><td class="line">270</td><td class="hits"></td><td class="source"> LIB_PATH + '/Driver/Cache/' + file,</td></tr><tr><td class="line">271</td><td class="hits"></td><td class="source"> THINK_LIB_PATH + '/Driver/Cache/' + file</td></tr><tr><td class="line">272</td><td class="hits"></td><td class="source"> ],</td></tr><tr><td class="line">273</td><td class="hits"></td><td class="source"> 'Db': [</td></tr><tr><td class="line">274</td><td class="hits"></td><td class="source"> LIB_PATH + '/Driver/Db/' + file,</td></tr><tr><td class="line">275</td><td class="hits"></td><td class="source"> THINK_LIB_PATH + '/Driver/Db/' + file</td></tr><tr><td class="line">276</td><td class="hits"></td><td class="source"> ],</td></tr><tr><td class="line">277</td><td class="hits"></td><td class="source"> 'Template': [</td></tr><tr><td class="line">278</td><td class="hits"></td><td class="source"> LIB_PATH + '/Driver/Template/' + file,</td></tr><tr><td class="line">279</td><td class="hits"></td><td class="source"> THINK_LIB_PATH + '/Driver/Template/' + file</td></tr><tr><td class="line">280</td><td class="hits"></td><td class="source"> ],</td></tr><tr><td class="line">281</td><td class="hits"></td><td class="source"> 'Socket': [</td></tr><tr><td class="line">282</td><td class="hits"></td><td class="source"> LIB_PATH + '/Driver/Socket/' + file,</td></tr><tr><td class="line">283</td><td class="hits"></td><td class="source"> THINK_LIB_PATH + '/Driver/Socket/' + file</td></tr><tr><td class="line">284</td><td class="hits"></td><td class="source"> ],</td></tr><tr><td class="line">285</td><td class="hits"></td><td class="source"> 'Session': [</td></tr><tr><td class="line">286</td><td class="hits"></td><td class="source"> LIB_PATH + '/Driver/Session/' + file,</td></tr><tr><td class="line">287</td><td class="hits"></td><td class="source"> THINK_LIB_PATH + '/Driver/Session/' + file</td></tr><tr><td class="line">288</td><td class="hits"></td><td class="source"> ]</td></tr><tr><td class="line">289</td><td class="hits"></td><td class="source"> };</td></tr><tr class="hit"><td class="line">290</td><td class="hits">1</td><td class="source"> var autoloadPath = C('autoload_path');</td></tr><tr class="hit"><td class="line">291</td><td class="hits">1</td><td class="source"> for(var type in autoloadPath){</td></tr><tr class="miss"><td class="line">292</td><td class="hits">0</td><td class="source"> var paths = autoloadPath[type];</td></tr><tr class="miss"><td class="line">293</td><td class="hits">0</td><td class="source"> var override = false;</td></tr><tr class="miss"><td class="line">294</td><td class="hits">0</td><td class="source"> if (!isArray(paths)) {</td></tr><tr class="miss"><td class="line">295</td><td class="hits">0</td><td class="source"> paths = [paths];</td></tr><tr class="miss"><td class="line">296</td><td class="hits">0</td><td class="source"> }else if (isBoolean(paths[0])) {</td></tr><tr class="miss"><td class="line">297</td><td class="hits">0</td><td class="source"> override = paths.shift();</td></tr><tr><td class="line">298</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">299</td><td class="hits">0</td><td class="source"> if (override) {</td></tr><tr class="miss"><td class="line">300</td><td class="hits">0</td><td class="source"> sysAutoloadPath[type] = paths; </td></tr><tr><td class="line">301</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">302</td><td class="hits">0</td><td class="source"> paths.push.apply(paths, sysAutoloadPath[type]);</td></tr><tr class="miss"><td class="line">303</td><td class="hits">0</td><td class="source"> sysAutoloadPath[type] = paths;</td></tr><tr><td class="line">304</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">305</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">306</td><td class="hits">1</td><td class="source"> autoloadPaths = sysAutoloadPath;</td></tr><tr><td class="line">307</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">308</td><td class="hits"></td><td class="source"> //thinkRequire的自动加载</td></tr><tr><td class="line">309</td><td class="hits"></td><td class="source"> autoload: function(cls){</td></tr><tr class="hit"><td class="line">310</td><td class="hits">19</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">311</td><td class="hits">19</td><td class="source"> var filepath = '';</td></tr><tr class="hit"><td class="line">312</td><td class="hits">19</td><td class="source"> var fn = function(item){</td></tr><tr class="hit"><td class="line">313</td><td class="hits">35</td><td class="source"> item = item.replace(/__CLASS__/g, cls);</td></tr><tr class="hit"><td class="line">314</td><td class="hits">35</td><td class="source"> if (isFile(item)) {</td></tr><tr class="hit"><td class="line">315</td><td class="hits">18</td><td class="source"> filepath = item;</td></tr><tr class="hit"><td class="line">316</td><td class="hits">18</td><td class="source"> return true;</td></tr><tr><td class="line">317</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">318</td><td class="hits"></td><td class="source"> };</td></tr><tr class="hit"><td class="line">319</td><td class="hits">19</td><td class="source"> for(var name in autoloadPaths){</td></tr><tr class="hit"><td class="line">320</td><td class="hits">72</td><td class="source"> var length = name.length;</td></tr><tr class="hit"><td class="line">321</td><td class="hits">72</td><td class="source"> if (cls.substr(0 - length) === name) {</td></tr><tr class="hit"><td class="line">322</td><td class="hits">18</td><td class="source"> var list = autoloadPaths[name];</td></tr><tr class="hit"><td class="line">323</td><td class="hits">18</td><td class="source"> list.some(fn);</td></tr><tr class="hit"><td class="line">324</td><td class="hits">18</td><td class="source"> if (filepath) {</td></tr><tr class="hit"><td class="line">325</td><td class="hits">18</td><td class="source"> if (!APP_DEBUG) {</td></tr><tr class="hit"><td class="line">326</td><td class="hits">18</td><td class="source"> aliasImport(cls, filepath);</td></tr><tr><td class="line">327</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">328</td><td class="hits">18</td><td class="source"> return filepath;</td></tr><tr><td class="line">329</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">330</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">331</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">332</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">333</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">334</td><td class="hits"></td><td class="source"> </td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/View.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Core/View.js</h2><div id="stats" class="high"><div class="percentage">76%</div><div class="sloc">42</div><div class="hits">32</div><div class="misses">10</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * view</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">module.exports = Class(function(){</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> tVar: {},</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> init: function(http){</td></tr><tr class="hit"><td class="line">10</td><td class="hits">1</td><td class="source"> this.http = http;</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> * 给变量赋值</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> assign: function(name, value){</td></tr><tr class="hit"><td class="line">19</td><td class="hits">2</td><td class="source"> if (name === undefined) {</td></tr><tr class="miss"><td class="line">20</td><td class="hits">0</td><td class="source"> return this.tVar;</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">22</td><td class="hits">2</td><td class="source"> if (isString(name) &amp;&amp; arguments.length === 1) {</td></tr><tr class="miss"><td class="line">23</td><td class="hits">0</td><td class="source"> return this.tVar[name];</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">25</td><td class="hits">2</td><td class="source"> if (isObject(name)) {</td></tr><tr class="miss"><td class="line">26</td><td class="hits">0</td><td class="source"> this.tVar = extend(this.tVar, name);</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="hit"><td class="line">28</td><td class="hits">2</td><td class="source"> this.tVar[name] = value;</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> * 获取变量的值</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> get: function(name){</td></tr><tr class="miss"><td class="line">37</td><td class="hits">0</td><td class="source"> if (!name) {</td></tr><tr class="miss"><td class="line">38</td><td class="hits">0</td><td class="source"> return this.tVar;</td></tr><tr><td class="line">39</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">40</td><td class="hits">0</td><td class="source"> return this.tVar[name];</td></tr><tr><td class="line">41</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> * 输出模版文件内容</td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> * @param {[type]} templateFile [description]</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source"> * @param {[type]} charset [description]</td></tr><tr><td class="line">46</td><td class="hits"></td><td class="source"> * @param {[type]} contentType [description]</td></tr><tr><td class="line">47</td><td class="hits"></td><td class="source"> * @param {[type]} content [description]</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">49</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> display: function(templateFile, charset, contentType, content){</td></tr><tr class="hit"><td class="line">51</td><td class="hits">1</td><td class="source"> var self = this;</td></tr><tr class="hit"><td class="line">52</td><td class="hits">1</td><td class="source"> return tag('view_init', this.http).then(function(){</td></tr><tr class="hit"><td class="line">53</td><td class="hits">1</td><td class="source"> return self.fetch(templateFile, content);</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> }).then(function(content){</td></tr><tr class="hit"><td class="line">55</td><td class="hits">1</td><td class="source"> self.render(content, charset, contentType);</td></tr><tr class="hit"><td class="line">56</td><td class="hits">1</td><td class="source"> return tag('view_end', self.http, content);</td></tr><tr><td class="line">57</td><td class="hits"></td><td class="source"> }).then(function(){</td></tr><tr class="hit"><td class="line">58</td><td class="hits">1</td><td class="source"> return self.http.end();</td></tr><tr><td class="line">59</td><td class="hits"></td><td class="source"> }).catch(function(){</td></tr><tr class="miss"><td class="line">60</td><td class="hits">0</td><td class="source"> return self.http.end();</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">62</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">63</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> * 渲染模版</td></tr><tr><td class="line">65</td><td class="hits"></td><td class="source"> * @param {[type]} content [description]</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> * @param {[type]} charset [description]</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> * @param {[type]} contentType [description]</td></tr><tr><td class="line">68</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">69</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">70</td><td class="hits"></td><td class="source"> render: function(content, charset, contentType){</td></tr><tr class="hit"><td class="line">71</td><td class="hits">1</td><td class="source"> if (!this.http.cthIsSend) {</td></tr><tr class="hit"><td class="line">72</td><td class="hits">1</td><td class="source"> if (charset === undefined) {</td></tr><tr class="hit"><td class="line">73</td><td class="hits">1</td><td class="source"> charset = C('encoding');</td></tr><tr><td class="line">74</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">75</td><td class="hits">1</td><td class="source"> if (contentType === undefined) {</td></tr><tr class="hit"><td class="line">76</td><td class="hits">1</td><td class="source"> contentType = C('tpl_content_type');</td></tr><tr><td class="line">77</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">78</td><td class="hits">1</td><td class="source"> this.http.setHeader('Content-Type', contentType + '; charset=' + charset);</td></tr><tr><td class="line">79</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">80</td><td class="hits">1</td><td class="source"> if (C('show_exec_time')) {</td></tr><tr class="miss"><td class="line">81</td><td class="hits">0</td><td class="source"> this.http.sendTime('Exec-Time');</td></tr><tr><td class="line">82</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">83</td><td class="hits">1</td><td class="source"> this.http.echo(content || '', C('encoding'));</td></tr><tr><td class="line">84</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">85</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">86</td><td class="hits"></td><td class="source"> * 获取模版文件内容</td></tr><tr><td class="line">87</td><td class="hits"></td><td class="source"> * @param {[type]} templateFile [description]</td></tr><tr><td class="line">88</td><td class="hits"></td><td class="source"> * @param {[type]} content [description]</td></tr><tr><td class="line">89</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">91</td><td class="hits"></td><td class="source"> fetch: function(templateFile, content){</td></tr><tr class="hit"><td class="line">92</td><td class="hits">1</td><td class="source"> var self = this;</td></tr><tr class="hit"><td class="line">93</td><td class="hits">1</td><td class="source"> var promise = getPromise('');</td></tr><tr class="hit"><td class="line">94</td><td class="hits">1</td><td class="source"> if (content === undefined) {</td></tr><tr class="hit"><td class="line">95</td><td class="hits">1</td><td class="source"> promise = tag('view_template', this.http, templateFile).then(function(file){</td></tr><tr class="hit"><td class="line">96</td><td class="hits">1</td><td class="source"> if (file &amp;&amp; isFile(file)) {</td></tr><tr class="hit"><td class="line">97</td><td class="hits">1</td><td class="source"> templateFile = file;</td></tr><tr><td class="line">98</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">99</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">100</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">101</td><td class="hits">1</td><td class="source"> return promise.then(function(){</td></tr><tr class="hit"><td class="line">102</td><td class="hits">1</td><td class="source"> if (!templateFile) {</td></tr><tr class="miss"><td class="line">103</td><td class="hits">0</td><td class="source"> return '';</td></tr><tr><td class="line">104</td><td class="hits"></td><td class="source"> }</td></tr><tr class="hit"><td class="line">105</td><td class="hits">1</td><td class="source"> return tag('view_parse', self.http, {</td></tr><tr><td class="line">106</td><td class="hits"></td><td class="source"> 'var': self.tVar,</td></tr><tr><td class="line">107</td><td class="hits"></td><td class="source"> 'file': templateFile,</td></tr><tr><td class="line">108</td><td class="hits"></td><td class="source"> 'content': content</td></tr><tr><td class="line">109</td><td class="hits"></td><td class="source"> }).then(function(content){</td></tr><tr class="hit"><td class="line">110</td><td class="hits">1</td><td class="source"> return tag('view_filter', self.http, content);</td></tr><tr><td class="line">111</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">112</td><td class="hits"></td><td class="source"> }).catch(function(err){</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source"> //输出模版解析异常</td></tr><tr class="miss"><td class="line">114</td><td class="hits">0</td><td class="source"> console.log(isError(err) ? err.stack : err);</td></tr><tr><td class="line">115</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">116</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">117</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">118</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Cache/FileCache.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Cache/FileCache.js</h2><div id="stats" class="terrible"><div class="percentage">5%</div><div class="sloc">67</div><div class="hits">4</div><div class="misses">63</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"><td class="line">1</td><td class="hits">1</td><td class="source">var fs = require('fs');</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * 基于文件的缓存</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">module.exports = Cache(function(){</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">8</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> gcType: 'FileCache',</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> init: function(options){</td></tr><tr class="miss"><td class="line">11</td><td class="hits">0</td><td class="source"> this.options = extend({</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> cache_path: C('cache_path'), //缓存目录</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> cache_path_level: 2, //缓存子目录深度</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> cache_file_suffix: C('cache_file_suffix') //缓存文件后缀名</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> }, options);</td></tr><tr class="miss"><td class="line">16</td><td class="hits">0</td><td class="source"> mkdir(this.options.cache_path);</td></tr><tr class="miss"><td class="line">17</td><td class="hits">0</td><td class="source"> this.gcType += ':' + this.options.cache_path;</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> </td></tr><tr class="miss"><td class="line">19</td><td class="hits">0</td><td class="source"> this.super_('init', this.options);</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> * 存储的缓存文件</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> getStoredFile: function(name){</td></tr><tr class="miss"><td class="line">27</td><td class="hits">0</td><td class="source"> name = md5(this.key || name);</td></tr><tr class="miss"><td class="line">28</td><td class="hits">0</td><td class="source"> var dir = name.split('').slice(0, this.options.cache_path_level).join('/');</td></tr><tr class="miss"><td class="line">29</td><td class="hits">0</td><td class="source"> mkdir(this.options.cache_path + '/' + dir);</td></tr><tr class="miss"><td class="line">30</td><td class="hits">0</td><td class="source"> var path = this.options.cache_path + '/' + dir + '/' + name + this.options.cache_file_suffix;</td></tr><tr class="miss"><td class="line">31</td><td class="hits">0</td><td class="source"> return path;</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> * 获取缓存返回promise</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> getData: function(name){</td></tr><tr class="miss"><td class="line">39</td><td class="hits">0</td><td class="source"> var filePath = this.getStoredFile(name);</td></tr><tr class="miss"><td class="line">40</td><td class="hits">0</td><td class="source"> if (!isFile(filePath)) {</td></tr><tr class="miss"><td class="line">41</td><td class="hits">0</td><td class="source"> return getPromise();</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">43</td><td class="hits">0</td><td class="source"> var deferred = getDefer();</td></tr><tr class="miss"><td class="line">44</td><td class="hits">0</td><td class="source"> fs.exists(filePath, function(exists){</td></tr><tr class="miss"><td class="line">45</td><td class="hits">0</td><td class="source"> if (!exists) {</td></tr><tr class="miss"><td class="line">46</td><td class="hits">0</td><td class="source"> return deferred.resolve();</td></tr><tr><td class="line">47</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">48</td><td class="hits">0</td><td class="source"> fs.readFile(filePath, {encoding: 'utf8'}, function(error, content){</td></tr><tr class="miss"><td class="line">49</td><td class="hits">0</td><td class="source"> if (error || !content) {</td></tr><tr class="miss"><td class="line">50</td><td class="hits">0</td><td class="source"> return deferred.resolve();</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">52</td><td class="hits">0</td><td class="source"> try{</td></tr><tr class="miss"><td class="line">53</td><td class="hits">0</td><td class="source"> var data = JSON.parse(content);</td></tr><tr class="miss"><td class="line">54</td><td class="hits">0</td><td class="source"> if (Date.now() &gt; data.expire) {</td></tr><tr class="miss"><td class="line">55</td><td class="hits">0</td><td class="source"> fs.unlink(filePath, function(){</td></tr><tr class="miss"><td class="line">56</td><td class="hits">0</td><td class="source"> return deferred.resolve();</td></tr><tr><td class="line">57</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">58</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">59</td><td class="hits">0</td><td class="source"> deferred.resolve(data.data);</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> }catch(e){</td></tr><tr><td class="line">62</td><td class="hits"></td><td class="source"> //异常时删除该文件</td></tr><tr class="miss"><td class="line">63</td><td class="hits">0</td><td class="source"> fs.unlink(filePath, function(){</td></tr><tr class="miss"><td class="line">64</td><td class="hits">0</td><td class="source"> return deferred.resolve();</td></tr><tr><td class="line">65</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">68</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">69</td><td class="hits">0</td><td class="source"> return deferred.promise;</td></tr><tr><td class="line">70</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">71</td><td class="hits"></td><td class="source"> get: function(name){</td></tr><tr class="miss"><td class="line">72</td><td class="hits">0</td><td class="source"> return this.getData().then(function(data){</td></tr><tr class="miss"><td class="line">73</td><td class="hits">0</td><td class="source"> return (data || {})[name];</td></tr><tr><td class="line">74</td><td class="hits"></td><td class="source"> })</td></tr><tr><td class="line">75</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">76</td><td class="hits"></td><td class="source"> setData: function(name, value, timeout){</td></tr><tr class="miss"><td class="line">77</td><td class="hits">0</td><td class="source"> if (isObject(name)) {</td></tr><tr class="miss"><td class="line">78</td><td class="hits">0</td><td class="source"> timeout = value;</td></tr><tr><td class="line">79</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">80</td><td class="hits">0</td><td class="source"> if (timeout === undefined) {</td></tr><tr class="miss"><td class="line">81</td><td class="hits">0</td><td class="source"> timeout = this.options.timeout;</td></tr><tr><td class="line">82</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">83</td><td class="hits">0</td><td class="source"> var filePath = this.getStoredFile(name);</td></tr><tr class="miss"><td class="line">84</td><td class="hits">0</td><td class="source"> var data = {</td></tr><tr><td class="line">85</td><td class="hits"></td><td class="source"> data: isObject(name) ? name : getObject(name, value),</td></tr><tr><td class="line">86</td><td class="hits"></td><td class="source"> expire: Date.now() + timeout * 1000,</td></tr><tr><td class="line">87</td><td class="hits"></td><td class="source"> timeout: timeout</td></tr><tr><td class="line">88</td><td class="hits"></td><td class="source"> };</td></tr><tr class="miss"><td class="line">89</td><td class="hits">0</td><td class="source"> var deferred = getDefer();</td></tr><tr class="miss"><td class="line">90</td><td class="hits">0</td><td class="source"> fs.writeFile(filePath, JSON.stringify(data), function(){</td></tr><tr><td class="line">91</td><td class="hits"></td><td class="source"> //修改缓存文件权限,避免不同账号下启动时可能会出现无权限的问题</td></tr><tr class="miss"><td class="line">92</td><td class="hits">0</td><td class="source"> chmod(filePath);</td></tr><tr class="miss"><td class="line">93</td><td class="hits">0</td><td class="source"> deferred.resolve();</td></tr><tr><td class="line">94</td><td class="hits"></td><td class="source"> })</td></tr><tr class="miss"><td class="line">95</td><td class="hits">0</td><td class="source"> return deferred.promise;</td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">97</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">98</td><td class="hits"></td><td class="source"> * 设置缓存</td></tr><tr><td class="line">99</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">100</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">101</td><td class="hits"></td><td class="source"> * @param {[type]} expire [description]</td></tr><tr><td class="line">102</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">103</td><td class="hits"></td><td class="source"> set: function(name, value, timeout){</td></tr><tr class="miss"><td class="line">104</td><td class="hits">0</td><td class="source"> return this.setData(name, value, timeout);</td></tr><tr><td class="line">105</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">106</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">107</td><td class="hits"></td><td class="source"> * 删除缓存</td></tr><tr><td class="line">108</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">109</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">110</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">111</td><td class="hits"></td><td class="source"> rm: function(name){</td></tr><tr class="miss"><td class="line">112</td><td class="hits">0</td><td class="source"> var filePath = this.getStoredFile(name);</td></tr><tr class="miss"><td class="line">113</td><td class="hits">0</td><td class="source"> if (isFile(filePath)) {</td></tr><tr class="miss"><td class="line">114</td><td class="hits">0</td><td class="source"> var deferred = getDefer();</td></tr><tr class="miss"><td class="line">115</td><td class="hits">0</td><td class="source"> fs.unlink(filePath, function(){</td></tr><tr class="miss"><td class="line">116</td><td class="hits">0</td><td class="source"> deferred.resolve();</td></tr><tr><td class="line">117</td><td class="hits"></td><td class="source"> })</td></tr><tr class="miss"><td class="line">118</td><td class="hits">0</td><td class="source"> return deferred.promise;</td></tr><tr><td class="line">119</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">120</td><td class="hits">0</td><td class="source"> return getPromise();</td></tr><tr><td class="line">121</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">122</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">123</td><td class="hits"></td><td class="source"> * gc</td></tr><tr><td class="line">124</td><td class="hits"></td><td class="source"> * @param {[type]} now [description]</td></tr><tr><td class="line">125</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">126</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">127</td><td class="hits"></td><td class="source"> gc: function(now, path){</td></tr><tr class="miss"><td class="line">128</td><td class="hits">0</td><td class="source"> path = path || this.options.cache_path;</td></tr><tr class="miss"><td class="line">129</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">130</td><td class="hits">0</td><td class="source"> var files = fs.readdirSync(path);</td></tr><tr class="miss"><td class="line">131</td><td class="hits">0</td><td class="source"> files.forEach(function(item){</td></tr><tr class="miss"><td class="line">132</td><td class="hits">0</td><td class="source"> var filePath = path + '/' + item;</td></tr><tr class="miss"><td class="line">133</td><td class="hits">0</td><td class="source"> var stat = fs.statSync(filePath);</td></tr><tr class="miss"><td class="line">134</td><td class="hits">0</td><td class="source"> if (stat.isDirectory()) {</td></tr><tr class="miss"><td class="line">135</td><td class="hits">0</td><td class="source"> self.gc(now, filePath);</td></tr><tr class="miss"><td class="line">136</td><td class="hits">0</td><td class="source"> }else if (stat.isFile()) {</td></tr><tr class="miss"><td class="line">137</td><td class="hits">0</td><td class="source"> var data = getFileContent(filePath);</td></tr><tr class="miss"><td class="line">138</td><td class="hits">0</td><td class="source"> try{</td></tr><tr class="miss"><td class="line">139</td><td class="hits">0</td><td class="source"> data = JSON.parse(data);</td></tr><tr class="miss"><td class="line">140</td><td class="hits">0</td><td class="source"> if (now &gt; data.expire) {</td></tr><tr class="miss"><td class="line">141</td><td class="hits">0</td><td class="source"> fs.unlink(filePath, function(){});</td></tr><tr><td class="line">142</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">143</td><td class="hits"></td><td class="source"> }catch(e){}</td></tr><tr><td class="line">144</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">145</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">146</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">147</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">148</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Cache/MemcacheCache.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Cache/MemcacheCache.js</h2><div id="stats" class="low"><div class="percentage">35%</div><div class="sloc">14</div><div class="hits">5</div><div class="misses">9</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"><td class="line">1</td><td class="hits">1</td><td class="source">var memcache = thinkRequire('MemcacheSocket');</td></tr><tr class="hit"><td class="line">2</td><td class="hits">1</td><td class="source">module.exports = Cache(function(){</td></tr><tr class="hit"><td class="line">3</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">4</td><td class="hits">1</td><td class="source"> var instance = null;</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source"> namePrefix: '__thinkjs__',</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> init: function(options){</td></tr><tr class="miss"><td class="line">8</td><td class="hits">0</td><td class="source"> this.super_('init', options);</td></tr><tr class="miss"><td class="line">9</td><td class="hits">0</td><td class="source"> if (!instance) {</td></tr><tr class="miss"><td class="line">10</td><td class="hits">0</td><td class="source"> instance = memcache(C('memcache_port'), C('memcache_host'));</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">12</td><td class="hits">0</td><td class="source"> this.handle = instance;</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> get: function(name){</td></tr><tr class="miss"><td class="line">15</td><td class="hits">0</td><td class="source"> return this.handle.get(this.namePrefix + name).then(function(value){</td></tr><tr class="miss"><td class="line">16</td><td class="hits">0</td><td class="source"> return value ? JSON.parse(value) : value;</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> })</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> set: function(name, value, timeout){</td></tr><tr class="miss"><td class="line">20</td><td class="hits">0</td><td class="source"> timeout = timeout || this.options.timeout;</td></tr><tr class="miss"><td class="line">21</td><td class="hits">0</td><td class="source"> return this.handle.set(this.namePrefix + name, JSON.stringify(value), timeout);</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> rm: function(name){</td></tr><tr class="miss"><td class="line">24</td><td class="hits">0</td><td class="source"> return this.handle.delete(this.namePrefix + name);</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Db/MysqlDb.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Db/MysqlDb.js</h2><div id="stats" class="terrible"><div class="percentage">8%</div><div class="sloc">61</div><div class="hits">5</div><div class="misses">56</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * mysql数据库</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">var mysqlSocket = thinkRequire('MysqlSocket');</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">module.exports = Db(function(){</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">8</td><td class="hits">1</td><td class="source"> var keyReg = /[,\'\&quot;\*\(\)`.\s]/;</td></tr><tr class="hit"><td class="line">9</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> init: function(config){</td></tr><tr class="miss"><td class="line">11</td><td class="hits">0</td><td class="source"> this.super_('init');</td></tr><tr class="miss"><td class="line">12</td><td class="hits">0</td><td class="source"> if (config) {</td></tr><tr class="miss"><td class="line">13</td><td class="hits">0</td><td class="source"> this.config = config;</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">15</td><td class="hits">0</td><td class="source"> this.lastInsertId = 0;</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> //查询等待</td></tr><tr class="miss"><td class="line">17</td><td class="hits">0</td><td class="source"> this.queryWaiting = {};</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> * 连接数据库</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> * @param {[type]} config [description]</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> * @param {[type]} linknum [description]</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source"> connect: function(config, linknum){</td></tr><tr class="miss"><td class="line">26</td><td class="hits">0</td><td class="source"> linknum = linknum || 0;</td></tr><tr class="miss"><td class="line">27</td><td class="hits">0</td><td class="source"> if (!this.linkIds[linknum]) {</td></tr><tr class="miss"><td class="line">28</td><td class="hits">0</td><td class="source"> config = config || this.config;</td></tr><tr class="miss"><td class="line">29</td><td class="hits">0</td><td class="source"> this.linkIds[linknum] = mysqlSocket(config);</td></tr><tr class="miss"><td class="line">30</td><td class="hits">0</td><td class="source"> this.connected = true;</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">32</td><td class="hits">0</td><td class="source"> return this.linkIds[linknum];</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> * 查询一条sql</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> * @param string str</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> * @return promise</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">39</td><td class="hits"></td><td class="source"> query: function(str){</td></tr><tr class="miss"><td class="line">40</td><td class="hits">0</td><td class="source"> this.initConnect(false);</td></tr><tr class="miss"><td class="line">41</td><td class="hits">0</td><td class="source"> if (!this.linkId) {</td></tr><tr class="miss"><td class="line">42</td><td class="hits">0</td><td class="source"> return getPromise('linkId is null', true);</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">44</td><td class="hits">0</td><td class="source"> this.queryStr = str;</td></tr><tr class="miss"><td class="line">45</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">46</td><td class="hits">0</td><td class="source"> if (!(str in this.queryWaiting)) {</td></tr><tr class="miss"><td class="line">47</td><td class="hits">0</td><td class="source"> this.queryWaiting[str] = [];</td></tr><tr class="miss"><td class="line">48</td><td class="hits">0</td><td class="source"> return this.linkId.query(str).then(function(data){</td></tr><tr class="miss"><td class="line">49</td><td class="hits">0</td><td class="source"> process.nextTick(function(){</td></tr><tr class="miss"><td class="line">50</td><td class="hits">0</td><td class="source"> self.queryWaiting[str].forEach(function(deferred){</td></tr><tr class="miss"><td class="line">51</td><td class="hits">0</td><td class="source"> deferred.resolve(data);</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">53</td><td class="hits">0</td><td class="source"> delete self.queryWaiting[str];</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> })</td></tr><tr class="miss"><td class="line">55</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">56</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">57</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">58</td><td class="hits">0</td><td class="source"> var deferred = getDefer();</td></tr><tr class="miss"><td class="line">59</td><td class="hits">0</td><td class="source"> this.queryWaiting[str].push(deferred);</td></tr><tr class="miss"><td class="line">60</td><td class="hits">0</td><td class="source"> return deferred.promise;</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">62</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">63</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> * 执行一条sql, 返回影响的行数</td></tr><tr><td class="line">65</td><td class="hits"></td><td class="source"> * @param {[type]} str [description]</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">68</td><td class="hits"></td><td class="source"> execute: function(str){</td></tr><tr class="miss"><td class="line">69</td><td class="hits">0</td><td class="source"> this.initConnect(false);</td></tr><tr class="miss"><td class="line">70</td><td class="hits">0</td><td class="source"> if (!this.linkId) {</td></tr><tr class="miss"><td class="line">71</td><td class="hits">0</td><td class="source"> return getPromise('linkId is null', true);</td></tr><tr><td class="line">72</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">73</td><td class="hits">0</td><td class="source"> this.queryStr = str;</td></tr><tr class="miss"><td class="line">74</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">75</td><td class="hits">0</td><td class="source"> return this.linkId.query(str).then(function(data){</td></tr><tr class="miss"><td class="line">76</td><td class="hits">0</td><td class="source"> self.lastInsertId = data.insertId;</td></tr><tr class="miss"><td class="line">77</td><td class="hits">0</td><td class="source"> return data.affectedRows || 0;</td></tr><tr><td class="line">78</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">79</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">80</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">81</td><td class="hits"></td><td class="source"> * 获取数据表字段信息</td></tr><tr><td class="line">82</td><td class="hits"></td><td class="source"> * @param string tableName 数据表名</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> * @return promise 返回一个promise</td></tr><tr><td class="line">84</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">85</td><td class="hits"></td><td class="source"> getFields: function(tableName){</td></tr><tr class="miss"><td class="line">86</td><td class="hits">0</td><td class="source"> var sql = 'SHOW COLUMNS FROM ' + this.parseKey(tableName);</td></tr><tr class="miss"><td class="line">87</td><td class="hits">0</td><td class="source"> return this.query(sql).then(function(data){</td></tr><tr class="miss"><td class="line">88</td><td class="hits">0</td><td class="source"> var ret = {};</td></tr><tr class="miss"><td class="line">89</td><td class="hits">0</td><td class="source"> data.forEach(function(item){</td></tr><tr class="miss"><td class="line">90</td><td class="hits">0</td><td class="source"> ret[item.Field] = {</td></tr><tr><td class="line">91</td><td class="hits"></td><td class="source"> 'name': item.Field,</td></tr><tr><td class="line">92</td><td class="hits"></td><td class="source"> 'type': item.Type,</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source"> 'notnull': item.Null === '',</td></tr><tr><td class="line">94</td><td class="hits"></td><td class="source"> 'default': item.Default,</td></tr><tr><td class="line">95</td><td class="hits"></td><td class="source"> 'primary': item.Key === 'PRI',</td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source"> 'unique': item.Key === 'UNI',</td></tr><tr><td class="line">97</td><td class="hits"></td><td class="source"> 'autoinc': item.Extra.toLowerCase() === 'auto_increment'</td></tr><tr><td class="line">98</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">99</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">100</td><td class="hits">0</td><td class="source"> return ret;</td></tr><tr><td class="line">101</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">102</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">103</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">104</td><td class="hits"></td><td class="source"> * 获取数据库的表信息</td></tr><tr><td class="line">105</td><td class="hits"></td><td class="source"> * @param {[type]} dbName [description]</td></tr><tr><td class="line">106</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">107</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">108</td><td class="hits"></td><td class="source"> getTables: function(dbName){</td></tr><tr class="miss"><td class="line">109</td><td class="hits">0</td><td class="source"> var sql = 'SHOW TABLES';</td></tr><tr class="miss"><td class="line">110</td><td class="hits">0</td><td class="source"> if (dbName) {</td></tr><tr class="miss"><td class="line">111</td><td class="hits">0</td><td class="source"> sql += ' FROM ' + dbName;</td></tr><tr><td class="line">112</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">113</td><td class="hits">0</td><td class="source"> return this.query(sql).then(function(data){</td></tr><tr class="miss"><td class="line">114</td><td class="hits">0</td><td class="source"> return data.map(function(item){</td></tr><tr class="miss"><td class="line">115</td><td class="hits">0</td><td class="source"> for(var key in item){</td></tr><tr class="miss"><td class="line">116</td><td class="hits">0</td><td class="source"> return item[key];</td></tr><tr><td class="line">117</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">118</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">119</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">120</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">121</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">122</td><td class="hits"></td><td class="source"> * 关闭连接</td></tr><tr><td class="line">123</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">124</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">125</td><td class="hits"></td><td class="source"> close: function(){</td></tr><tr class="miss"><td class="line">126</td><td class="hits">0</td><td class="source"> if (this.linkId) {</td></tr><tr class="miss"><td class="line">127</td><td class="hits">0</td><td class="source"> this.linkId.close();</td></tr><tr class="miss"><td class="line">128</td><td class="hits">0</td><td class="source"> this.linkId = null;</td></tr><tr><td class="line">129</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">130</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">131</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">132</td><td class="hits"></td><td class="source"> * 解析key</td></tr><tr><td class="line">133</td><td class="hits"></td><td class="source"> * @param {[type]} key [description]</td></tr><tr><td class="line">134</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">135</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">136</td><td class="hits"></td><td class="source"> parseKey: function(key){</td></tr><tr class="miss"><td class="line">137</td><td class="hits">0</td><td class="source"> key = (key || '').trim();</td></tr><tr class="miss"><td class="line">138</td><td class="hits">0</td><td class="source"> if (!keyReg.test(key)) {</td></tr><tr class="miss"><td class="line">139</td><td class="hits">0</td><td class="source"> key = '`' + key + '`';</td></tr><tr><td class="line">140</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">141</td><td class="hits">0</td><td class="source"> return key;</td></tr><tr><td class="line">142</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">143</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">144</td><td class="hits"></td><td class="source"> * 获取最后插入的id</td></tr><tr><td class="line">145</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">146</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">147</td><td class="hits"></td><td class="source"> getLastInsertId: function(){</td></tr><tr class="miss"><td class="line">148</td><td class="hits">0</td><td class="source"> return this.lastInsertId;</td></tr><tr><td class="line">149</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">150</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">151</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Session/DbSession.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Session/DbSession.js</h2><div id="stats" class="terrible"><div class="percentage">9%</div><div class="sloc">33</div><div class="hits">3</div><div class="misses">30</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * DbSession</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * 需要在数据库中建立对应的数据表</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> *</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> * DROP TABLE IF EXISTS `think_session`;</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source"> CREATE TABLE `think_session` (</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> `id` int(11) unsigned NOT NULL AUTO_INCREMENT,</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> `key` varchar(255) NOT NULL DEFAULT '',</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> `data` text,</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> `expire` bigint(11) NOT NULL,</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> PRIMARY KEY (`id`),</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> UNIQUE KEY `cookie` (`key`),</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> KEY `expire` (`expire`)</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> *</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> * </td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">19</td><td class="hits">1</td><td class="source">module.exports = Cache(function(){</td></tr><tr class="hit"><td class="line">20</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">21</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> * gc类型</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> * @type {String}</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> gcType: 'DbSession',</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> * [init description]</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> init: function(options){</td></tr><tr class="miss"><td class="line">33</td><td class="hits">0</td><td class="source"> this.super_('init', options);</td></tr><tr class="miss"><td class="line">34</td><td class="hits">0</td><td class="source"> this.key = this.options.cookie;</td></tr><tr class="miss"><td class="line">35</td><td class="hits">0</td><td class="source"> this.data = {};</td></tr><tr class="miss"><td class="line">36</td><td class="hits">0</td><td class="source"> this.initData();</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">39</td><td class="hits"></td><td class="source"> * 初始化数据</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">41</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> initData: function(){</td></tr><tr class="miss"><td class="line">43</td><td class="hits">0</td><td class="source"> if (!this.promise) {</td></tr><tr class="miss"><td class="line">44</td><td class="hits">0</td><td class="source"> var model = D('Session');</td></tr><tr class="miss"><td class="line">45</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">46</td><td class="hits">0</td><td class="source"> this.promise = model.where({key: this.key}).find().then(function(data){</td></tr><tr class="miss"><td class="line">47</td><td class="hits">0</td><td class="source"> self.data = {};</td></tr><tr class="miss"><td class="line">48</td><td class="hits">0</td><td class="source"> if (isEmpty(data)) {</td></tr><tr class="miss"><td class="line">49</td><td class="hits">0</td><td class="source"> return model.add({</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> key: self.key,</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> expire: Date.now() + self.options.timeout * 1000</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">54</td><td class="hits">0</td><td class="source"> if (Date.now() &gt; data.expire) {</td></tr><tr class="miss"><td class="line">55</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">56</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">57</td><td class="hits">0</td><td class="source"> self.data = JSON.parse(data.data || '{}');</td></tr><tr><td class="line">58</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">59</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">60</td><td class="hits">0</td><td class="source"> return this.promise;</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">62</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">63</td><td class="hits"></td><td class="source"> * 获取</td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">65</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> get: function(name){</td></tr><tr class="miss"><td class="line">68</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">69</td><td class="hits">0</td><td class="source"> return this.initData().then(function(){</td></tr><tr class="miss"><td class="line">70</td><td class="hits">0</td><td class="source"> return self.data[name];</td></tr><tr><td class="line">71</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">72</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">73</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">74</td><td class="hits"></td><td class="source"> * 设置</td></tr><tr><td class="line">75</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">76</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">77</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">78</td><td class="hits"></td><td class="source"> set: function(name, value){</td></tr><tr class="miss"><td class="line">79</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">80</td><td class="hits">0</td><td class="source"> return this.initData().then(function(){</td></tr><tr class="miss"><td class="line">81</td><td class="hits">0</td><td class="source"> self.data[name] = value;</td></tr><tr><td class="line">82</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">84</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">85</td><td class="hits"></td><td class="source"> * 删除</td></tr><tr><td class="line">86</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">87</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">88</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">89</td><td class="hits"></td><td class="source"> rm: function(name){</td></tr><tr class="miss"><td class="line">90</td><td class="hits">0</td><td class="source"> if (this.data) {</td></tr><tr class="miss"><td class="line">91</td><td class="hits">0</td><td class="source"> delete this.data[name];</td></tr><tr><td class="line">92</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">93</td><td class="hits">0</td><td class="source"> return getPromise();</td></tr><tr><td class="line">94</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">95</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source"> * 将数据保存到数据库中</td></tr><tr><td class="line">97</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">98</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">99</td><td class="hits"></td><td class="source"> flush: function(){</td></tr><tr class="miss"><td class="line">100</td><td class="hits">0</td><td class="source"> var model = D('Session');</td></tr><tr class="miss"><td class="line">101</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">102</td><td class="hits">0</td><td class="source"> var data = {</td></tr><tr><td class="line">103</td><td class="hits"></td><td class="source"> expire: Date.now() + self.options.timeout * 1000,</td></tr><tr><td class="line">104</td><td class="hits"></td><td class="source"> data: JSON.stringify(self.data)</td></tr><tr><td class="line">105</td><td class="hits"></td><td class="source"> };</td></tr><tr class="miss"><td class="line">106</td><td class="hits">0</td><td class="source"> return this.initData().then(function(){</td></tr><tr class="miss"><td class="line">107</td><td class="hits">0</td><td class="source"> return model.where({key: self.key}).update(data);</td></tr><tr><td class="line">108</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">109</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">110</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">111</td><td class="hits"></td><td class="source"> * [gc description]</td></tr><tr><td class="line">112</td><td class="hits"></td><td class="source"> * @param {[type]} now [description]</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">114</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">115</td><td class="hits"></td><td class="source"> gc: function(now){</td></tr><tr class="miss"><td class="line">116</td><td class="hits">0</td><td class="source"> return D('Session').where({</td></tr><tr><td class="line">117</td><td class="hits"></td><td class="source"> expire: ['&lt;', now]</td></tr><tr><td class="line">118</td><td class="hits"></td><td class="source"> }).delete();</td></tr><tr><td class="line">119</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">120</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">121</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Session/FileSession.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Session/FileSession.js</h2><div id="stats" class="terrible"><div class="percentage">15%</div><div class="sloc">26</div><div class="hits">4</div><div class="misses">22</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * 文件Session</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">var os = require('os');</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source">module.exports = Class(function(){</td></tr><tr class="hit"><td class="line">8</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">9</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> gcType: 'FileSession',</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> * 差异化的init</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> init: function(options){</td></tr><tr class="miss"><td class="line">16</td><td class="hits">0</td><td class="source"> options = options || {};</td></tr><tr class="miss"><td class="line">17</td><td class="hits">0</td><td class="source"> options.cache_path = C('session_path') || (os.tmpdir() + '/thinkjs');</td></tr><tr class="miss"><td class="line">18</td><td class="hits">0</td><td class="source"> this.super_('init', options);</td></tr><tr class="miss"><td class="line">19</td><td class="hits">0</td><td class="source"> this.key = options.cookie;</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> initData: function(){</td></tr><tr class="miss"><td class="line">22</td><td class="hits">0</td><td class="source"> if (!this.promise) {</td></tr><tr class="miss"><td class="line">23</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">24</td><td class="hits">0</td><td class="source"> this.promise = this.getData().then(function(data){</td></tr><tr class="miss"><td class="line">25</td><td class="hits">0</td><td class="source"> self.sessionData = data || {};</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> })</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">28</td><td class="hits">0</td><td class="source"> return this.promise;</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> get: function(name){</td></tr><tr class="miss"><td class="line">31</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">32</td><td class="hits">0</td><td class="source"> return this.initData().then(function(){</td></tr><tr class="miss"><td class="line">33</td><td class="hits">0</td><td class="source"> return self.sessionData[name];</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> set: function(name, value, timeout){</td></tr><tr class="miss"><td class="line">37</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">38</td><td class="hits">0</td><td class="source"> return this.initData().then(function(){</td></tr><tr class="miss"><td class="line">39</td><td class="hits">0</td><td class="source"> self.sessionData[name] = value;</td></tr><tr class="miss"><td class="line">40</td><td class="hits">0</td><td class="source"> if (timeout) {</td></tr><tr class="miss"><td class="line">41</td><td class="hits">0</td><td class="source"> self.options.timeout = timeout;</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source"> rm: function(){</td></tr><tr class="miss"><td class="line">46</td><td class="hits">0</td><td class="source"> this.sessionData = {};</td></tr><tr class="miss"><td class="line">47</td><td class="hits">0</td><td class="source"> return getPromise();</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">49</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> * 将数据写入到文件中</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> flush: function(){</td></tr><tr class="miss"><td class="line">54</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">55</td><td class="hits">0</td><td class="source"> return this.initData().then(function(){</td></tr><tr class="miss"><td class="line">56</td><td class="hits">0</td><td class="source"> return self.setData(self.sessionData);</td></tr><tr><td class="line">57</td><td class="hits"></td><td class="source"> })</td></tr><tr><td class="line">58</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">59</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source">}, thinkRequire('FileCache'));</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Socket/MemcacheSocket.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Socket/MemcacheSocket.js</h2><div id="stats" class="terrible"><div class="percentage">12%</div><div class="sloc">124</div><div class="hits">15</div><div class="misses">109</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"><td class="line">1</td><td class="hits">1</td><td class="source">var net = require('net');</td></tr><tr class="hit"><td class="line">2</td><td class="hits">1</td><td class="source">var EventEmitter = require('events').EventEmitter;</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">4</td><td class="hits">1</td><td class="source">var CRLF = '\r\n'; //换行符</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">var CRLF_LENGTH = CRLF.length;</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">var ERRORS = ['ERROR', 'NOT_FOUND', 'CLIENT_ERROR', 'SERVER_ERROR']; //错误</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source">var ERRORS_LENGTH = ERRORS.length;</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source">//读取一行数据</td></tr><tr class="hit"><td class="line">10</td><td class="hits">1</td><td class="source">function readLine(string){</td></tr><tr class="miss"><td class="line">11</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">12</td><td class="hits">0</td><td class="source"> var pos = string.indexOf(CRLF);</td></tr><tr class="miss"><td class="line">13</td><td class="hits">0</td><td class="source"> if (pos &gt; -1) {</td></tr><tr class="miss"><td class="line">14</td><td class="hits">0</td><td class="source"> return string.substr(0, pos);</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">16</td><td class="hits">0</td><td class="source"> return string;</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source">}</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> * memcache类</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">22</td><td class="hits">1</td><td class="source">module.exports = Class(function(){</td></tr><tr class="hit"><td class="line">23</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">24</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source"> init: function(port, hostname){</td></tr><tr class="miss"><td class="line">26</td><td class="hits">0</td><td class="source"> EventEmitter.call(this);</td></tr><tr class="miss"><td class="line">27</td><td class="hits">0</td><td class="source"> this.port = port || 11211;</td></tr><tr class="miss"><td class="line">28</td><td class="hits">0</td><td class="source"> this.hostname = hostname || 'localhost';</td></tr><tr class="miss"><td class="line">29</td><td class="hits">0</td><td class="source"> this.buffer = '';</td></tr><tr class="miss"><td class="line">30</td><td class="hits">0</td><td class="source"> this.callbacks = []; //回调函数</td></tr><tr class="miss"><td class="line">31</td><td class="hits">0</td><td class="source"> this.handle = null; //socket连接句柄</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> * 建立连接</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> connect: function(){</td></tr><tr class="miss"><td class="line">38</td><td class="hits">0</td><td class="source"> if (this.handle) {</td></tr><tr class="miss"><td class="line">39</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">41</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">42</td><td class="hits">0</td><td class="source"> var deferred = getDefer();</td></tr><tr class="miss"><td class="line">43</td><td class="hits">0</td><td class="source"> this.handle = net.createConnection(this.port, this.host);</td></tr><tr class="miss"><td class="line">44</td><td class="hits">0</td><td class="source"> this.handle.on('connect', function(){</td></tr><tr class="miss"><td class="line">45</td><td class="hits">0</td><td class="source"> this.setTimeout(0);</td></tr><tr class="miss"><td class="line">46</td><td class="hits">0</td><td class="source"> this.setNoDelay();</td></tr><tr class="miss"><td class="line">47</td><td class="hits">0</td><td class="source"> self.emit('connect');</td></tr><tr class="miss"><td class="line">48</td><td class="hits">0</td><td class="source"> deferred.resolve();</td></tr><tr><td class="line">49</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">50</td><td class="hits">0</td><td class="source"> this.handle.on('data', function(data){</td></tr><tr class="miss"><td class="line">51</td><td class="hits">0</td><td class="source"> self.buffer += data.toString();</td></tr><tr class="miss"><td class="line">52</td><td class="hits">0</td><td class="source"> self.handleData();</td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">54</td><td class="hits">0</td><td class="source"> this.handle.on('end', function(){</td></tr><tr class="miss"><td class="line">55</td><td class="hits">0</td><td class="source"> self.handle.end();</td></tr><tr class="miss"><td class="line">56</td><td class="hits">0</td><td class="source"> self.handle = null;</td></tr><tr><td class="line">57</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">58</td><td class="hits">0</td><td class="source"> this.handle.on('close', function(){</td></tr><tr class="miss"><td class="line">59</td><td class="hits">0</td><td class="source"> self.handle = null;</td></tr><tr class="miss"><td class="line">60</td><td class="hits">0</td><td class="source"> self.emit('close');</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">62</td><td class="hits">0</td><td class="source"> this.handle.on('timeout', function(){</td></tr><tr class="miss"><td class="line">63</td><td class="hits">0</td><td class="source"> self.handle = null;</td></tr><tr class="miss"><td class="line">64</td><td class="hits">0</td><td class="source"> self.emit('timeout');</td></tr><tr><td class="line">65</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">66</td><td class="hits">0</td><td class="source"> this.handle.on('error', function(error){</td></tr><tr class="miss"><td class="line">67</td><td class="hits">0</td><td class="source"> self.handle = null;</td></tr><tr class="miss"><td class="line">68</td><td class="hits">0</td><td class="source"> self.emit('error', error);</td></tr><tr><td class="line">69</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">70</td><td class="hits">0</td><td class="source"> this.promise = deferred.promise;</td></tr><tr class="miss"><td class="line">71</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">72</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">73</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">74</td><td class="hits"></td><td class="source"> * 处理接收的数据</td></tr><tr><td class="line">75</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">76</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">77</td><td class="hits"></td><td class="source"> handleData: function(){</td></tr><tr class="miss"><td class="line">78</td><td class="hits">0</td><td class="source"> while(this.buffer.length &gt; 0){</td></tr><tr class="miss"><td class="line">79</td><td class="hits">0</td><td class="source"> var result = this.getHandleResult(this.buffer);</td></tr><tr class="miss"><td class="line">80</td><td class="hits">0</td><td class="source"> if(result === false){</td></tr><tr class="miss"><td class="line">81</td><td class="hits">0</td><td class="source"> break;</td></tr><tr><td class="line">82</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">83</td><td class="hits">0</td><td class="source"> var value = result[0];</td></tr><tr class="miss"><td class="line">84</td><td class="hits">0</td><td class="source"> var pos = result[1];</td></tr><tr class="miss"><td class="line">85</td><td class="hits">0</td><td class="source"> var error = result[2];</td></tr><tr class="miss"><td class="line">86</td><td class="hits">0</td><td class="source"> if (pos &gt; this.buffer.length) {</td></tr><tr class="miss"><td class="line">87</td><td class="hits">0</td><td class="source"> break;</td></tr><tr><td class="line">88</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">89</td><td class="hits">0</td><td class="source"> this.buffer = this.buffer.substring(pos);</td></tr><tr class="miss"><td class="line">90</td><td class="hits">0</td><td class="source"> var callback = this.callbacks.shift();</td></tr><tr class="miss"><td class="line">91</td><td class="hits">0</td><td class="source"> if (callback &amp;&amp; callback.callback) {</td></tr><tr class="miss"><td class="line">92</td><td class="hits">0</td><td class="source"> callback.callback(error, value);</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">94</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">95</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source"> getHandleResult: function(buffer){</td></tr><tr class="miss"><td class="line">97</td><td class="hits">0</td><td class="source"> if (buffer.indexOf(CRLF) === -1) {</td></tr><tr class="miss"><td class="line">98</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">99</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">100</td><td class="hits">0</td><td class="source"> for(var i = 0; i &lt; ERRORS_LENGTH; i++){</td></tr><tr class="miss"><td class="line">101</td><td class="hits">0</td><td class="source"> var item = ERRORS[i];</td></tr><tr class="miss"><td class="line">102</td><td class="hits">0</td><td class="source"> if (buffer.indexOf(item) &gt; -1) {</td></tr><tr class="miss"><td class="line">103</td><td class="hits">0</td><td class="source"> return this.handleError(buffer);</td></tr><tr><td class="line">104</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">105</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">106</td><td class="hits">0</td><td class="source"> var callback = this.callbacks[0];</td></tr><tr class="miss"><td class="line">107</td><td class="hits">0</td><td class="source"> if (callback &amp;&amp; callback.type) {</td></tr><tr class="miss"><td class="line">108</td><td class="hits">0</td><td class="source"> return this['handle' + ucfirst(callback.type)](buffer);</td></tr><tr><td class="line">109</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">110</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">111</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">112</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source"> * 处理错误</td></tr><tr><td class="line">114</td><td class="hits"></td><td class="source"> * @param {[type]} buffer [description]</td></tr><tr><td class="line">115</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">116</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">117</td><td class="hits"></td><td class="source"> handleError: function(buffer){</td></tr><tr class="miss"><td class="line">118</td><td class="hits">0</td><td class="source"> var line = readLine(buffer);</td></tr><tr class="miss"><td class="line">119</td><td class="hits">0</td><td class="source"> return [null, line.length + CRLF_LENGTH, line];</td></tr><tr><td class="line">120</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">121</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">122</td><td class="hits"></td><td class="source"> * 处理获取数据</td></tr><tr><td class="line">123</td><td class="hits"></td><td class="source"> * @param {[type]} buffer [description]</td></tr><tr><td class="line">124</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">125</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">126</td><td class="hits"></td><td class="source"> handleGet: function(buffer){</td></tr><tr class="miss"><td class="line">127</td><td class="hits">0</td><td class="source"> var value = null;</td></tr><tr class="miss"><td class="line">128</td><td class="hits">0</td><td class="source"> var end = 3;</td></tr><tr class="miss"><td class="line">129</td><td class="hits">0</td><td class="source"> var resultLen = 0;</td></tr><tr class="miss"><td class="line">130</td><td class="hits">0</td><td class="source"> var firstPos;</td></tr><tr class="miss"><td class="line">131</td><td class="hits">0</td><td class="source"> if (buffer.indexOf('END') === 0) {</td></tr><tr class="miss"><td class="line">132</td><td class="hits">0</td><td class="source"> return [value, end + CRLF_LENGTH];</td></tr><tr class="miss"><td class="line">133</td><td class="hits">0</td><td class="source"> }else if (buffer.indexOf('VALUE') === 0 &amp;&amp; buffer.indexOf('END') &gt; -1) {</td></tr><tr class="miss"><td class="line">134</td><td class="hits">0</td><td class="source"> firstPos = buffer.indexOf(CRLF) + CRLF_LENGTH;</td></tr><tr class="miss"><td class="line">135</td><td class="hits">0</td><td class="source"> var endPos = buffer.indexOf('END');</td></tr><tr class="miss"><td class="line">136</td><td class="hits">0</td><td class="source"> resultLen = endPos - firstPos - CRLF_LENGTH;</td></tr><tr class="miss"><td class="line">137</td><td class="hits">0</td><td class="source"> value = buffer.substr(firstPos, resultLen);</td></tr><tr class="miss"><td class="line">138</td><td class="hits">0</td><td class="source"> return [value, firstPos + parseInt(resultLen, 10) + CRLF_LENGTH + end + CRLF_LENGTH];</td></tr><tr><td class="line">139</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">140</td><td class="hits">0</td><td class="source"> firstPos = buffer.indexOf(CRLF) + CRLF_LENGTH;</td></tr><tr class="miss"><td class="line">141</td><td class="hits">0</td><td class="source"> resultLen = buffer.substr(0, firstPos).split(' ')[3];</td></tr><tr class="miss"><td class="line">142</td><td class="hits">0</td><td class="source"> value = buffer.substr(firstPos, resultLen);</td></tr><tr class="miss"><td class="line">143</td><td class="hits">0</td><td class="source"> return [value, firstPos + parseInt(resultLen) + CRLF_LENGTH + end + CRLF_LENGTH];</td></tr><tr><td class="line">144</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">145</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">146</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">147</td><td class="hits"></td><td class="source"> * 处理简单数据</td></tr><tr><td class="line">148</td><td class="hits"></td><td class="source"> * @param {[type]} buffer [description]</td></tr><tr><td class="line">149</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">150</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">151</td><td class="hits"></td><td class="source"> handleSimple: function(buffer){</td></tr><tr class="miss"><td class="line">152</td><td class="hits">0</td><td class="source"> var line = readLine(buffer);</td></tr><tr class="miss"><td class="line">153</td><td class="hits">0</td><td class="source"> return [line, line.length + CRLF_LENGTH, null];</td></tr><tr><td class="line">154</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">155</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">156</td><td class="hits"></td><td class="source"> * 版本号</td></tr><tr><td class="line">157</td><td class="hits"></td><td class="source"> * @param {[type]} buffer [description]</td></tr><tr><td class="line">158</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">159</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">160</td><td class="hits"></td><td class="source"> handleVersion: function(buffer){</td></tr><tr class="miss"><td class="line">161</td><td class="hits">0</td><td class="source"> var pos = buffer.indexOf(CRLF);</td></tr><tr><td class="line">162</td><td class="hits"></td><td class="source"> //8 is length of 'VERSION '</td></tr><tr class="miss"><td class="line">163</td><td class="hits">0</td><td class="source"> var value = buffer.substr(8, pos - 8);</td></tr><tr class="miss"><td class="line">164</td><td class="hits">0</td><td class="source"> return [value, pos + CRLF_LENGTH, null];</td></tr><tr><td class="line">165</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">166</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">167</td><td class="hits"></td><td class="source"> * 查询</td></tr><tr><td class="line">168</td><td class="hits"></td><td class="source"> * @param {[type]} query [description]</td></tr><tr><td class="line">169</td><td class="hits"></td><td class="source"> * @param {[type]} type [description]</td></tr><tr><td class="line">170</td><td class="hits"></td><td class="source"> * @param {Function} callback [description]</td></tr><tr><td class="line">171</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">172</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">173</td><td class="hits"></td><td class="source"> query: function(query, type){</td></tr><tr class="miss"><td class="line">174</td><td class="hits">0</td><td class="source"> this.connect();</td></tr><tr class="miss"><td class="line">175</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">176</td><td class="hits">0</td><td class="source"> var deferred = getDefer();</td></tr><tr class="miss"><td class="line">177</td><td class="hits">0</td><td class="source"> var callback = function(error, value){</td></tr><tr class="miss"><td class="line">178</td><td class="hits">0</td><td class="source"> return error ? deferred.reject(error) : deferred.resolve(value);</td></tr><tr><td class="line">179</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">180</td><td class="hits">0</td><td class="source"> this.promise.then(function(){</td></tr><tr class="miss"><td class="line">181</td><td class="hits">0</td><td class="source"> self.callbacks.push({type: type, callback: callback});</td></tr><tr class="miss"><td class="line">182</td><td class="hits">0</td><td class="source"> self.handle.write(query + CRLF);</td></tr><tr><td class="line">183</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">184</td><td class="hits">0</td><td class="source"> return deferred.promise;</td></tr><tr><td class="line">185</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">186</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">187</td><td class="hits"></td><td class="source"> * 获取</td></tr><tr><td class="line">188</td><td class="hits"></td><td class="source"> * @param {[type]} key [description]</td></tr><tr><td class="line">189</td><td class="hits"></td><td class="source"> * @param {Function} callback [description]</td></tr><tr><td class="line">190</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">191</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">192</td><td class="hits"></td><td class="source"> get: function(key){</td></tr><tr class="miss"><td class="line">193</td><td class="hits">0</td><td class="source"> return this.query('get ' + key, 'get');</td></tr><tr><td class="line">194</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">195</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">196</td><td class="hits"></td><td class="source"> * 存储</td></tr><tr><td class="line">197</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">198</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">199</td><td class="hits"></td><td class="source"> store: function(key, value, type, lifetime, flags){</td></tr><tr class="miss"><td class="line">200</td><td class="hits">0</td><td class="source"> lifetime = lifetime || 0;</td></tr><tr class="miss"><td class="line">201</td><td class="hits">0</td><td class="source"> flags = flags || 0;</td></tr><tr class="miss"><td class="line">202</td><td class="hits">0</td><td class="source"> var length = Buffer.byteLength(value.toString());</td></tr><tr class="miss"><td class="line">203</td><td class="hits">0</td><td class="source"> var query = [type, key, flags, lifetime, length].join(' ') + CRLF + value;</td></tr><tr class="miss"><td class="line">204</td><td class="hits">0</td><td class="source"> return this.query(query, 'simple');</td></tr><tr><td class="line">205</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">206</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">207</td><td class="hits"></td><td class="source"> * 删除</td></tr><tr><td class="line">208</td><td class="hits"></td><td class="source"> * @param {[type]} key [description]</td></tr><tr><td class="line">209</td><td class="hits"></td><td class="source"> * @param {Function} callback [description]</td></tr><tr><td class="line">210</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">211</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">212</td><td class="hits"></td><td class="source"> delete: function(key){</td></tr><tr class="miss"><td class="line">213</td><td class="hits">0</td><td class="source"> return this.query('delete ' + key, 'simple');</td></tr><tr><td class="line">214</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">215</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">216</td><td class="hits"></td><td class="source"> * 获取版本号</td></tr><tr><td class="line">217</td><td class="hits"></td><td class="source"> * @param {Function} callback [description]</td></tr><tr><td class="line">218</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">219</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">220</td><td class="hits"></td><td class="source"> version: function(){</td></tr><tr class="miss"><td class="line">221</td><td class="hits">0</td><td class="source"> return this.query('version', 'version');</td></tr><tr><td class="line">222</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">223</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">224</td><td class="hits"></td><td class="source"> * 增长</td></tr><tr><td class="line">225</td><td class="hits"></td><td class="source"> * @param {[type]} key [description]</td></tr><tr><td class="line">226</td><td class="hits"></td><td class="source"> * @param {[type]} step [description]</td></tr><tr><td class="line">227</td><td class="hits"></td><td class="source"> * @param {Function} callback [description]</td></tr><tr><td class="line">228</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">229</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">230</td><td class="hits"></td><td class="source"> increment: function(key, step){</td></tr><tr class="miss"><td class="line">231</td><td class="hits">0</td><td class="source"> step = step || 1;</td></tr><tr class="miss"><td class="line">232</td><td class="hits">0</td><td class="source"> return this.query('incr ' + key + ' ' + step, 'simple');</td></tr><tr><td class="line">233</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">234</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">235</td><td class="hits"></td><td class="source"> * 减少</td></tr><tr><td class="line">236</td><td class="hits"></td><td class="source"> * @param {[type]} key [description]</td></tr><tr><td class="line">237</td><td class="hits"></td><td class="source"> * @param {[type]} step [description]</td></tr><tr><td class="line">238</td><td class="hits"></td><td class="source"> * @param {Function} callback [description]</td></tr><tr><td class="line">239</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">240</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">241</td><td class="hits"></td><td class="source"> decrement: function(key, step){</td></tr><tr class="miss"><td class="line">242</td><td class="hits">0</td><td class="source"> step = step || 1;</td></tr><tr class="miss"><td class="line">243</td><td class="hits">0</td><td class="source"> return this.query('decr ' + key + ' ' + step, 'simple');</td></tr><tr><td class="line">244</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">245</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">246</td><td class="hits"></td><td class="source"> * 关闭</td></tr><tr><td class="line">247</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">248</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">249</td><td class="hits"></td><td class="source"> close: function(){</td></tr><tr class="miss"><td class="line">250</td><td class="hits">0</td><td class="source"> if (this.handle &amp;&amp; this.handle.readyState === 'open') {</td></tr><tr class="miss"><td class="line">251</td><td class="hits">0</td><td class="source"> this.handle.end();</td></tr><tr class="miss"><td class="line">252</td><td class="hits">0</td><td class="source"> this.handle = null;</td></tr><tr><td class="line">253</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">254</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">255</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">256</td><td class="hits"></td><td class="source">}, EventEmitter).extend(function(){</td></tr><tr class="hit"><td class="line">257</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">258</td><td class="hits">1</td><td class="source"> var result = {};</td></tr><tr class="hit"><td class="line">259</td><td class="hits">1</td><td class="source"> ['set', 'add', 'replace', 'append', 'prepend'].forEach(function(item){</td></tr><tr class="hit"><td class="line">260</td><td class="hits">5</td><td class="source"> result[item] = function(key, value, callback, lifetime, flags){</td></tr><tr class="miss"><td class="line">261</td><td class="hits">0</td><td class="source"> return this.store(key, value, item, callback, lifetime, flags);</td></tr><tr><td class="line">262</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">263</td><td class="hits"></td><td class="source"> });</td></tr><tr class="hit"><td class="line">264</td><td class="hits">1</td><td class="source"> return result;</td></tr><tr><td class="line">265</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Socket/MysqlSocket.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Socket/MysqlSocket.js</h2><div id="stats" class="terrible"><div class="percentage">8%</div><div class="sloc">45</div><div class="hits">4</div><div class="misses">41</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * mysql socket</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source">//暂时使用mysql库</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source">var mysql = require('mysql');</td></tr><tr class="hit"><td class="line">8</td><td class="hits">1</td><td class="source">module.exports = Class(function(){</td></tr><tr class="hit"><td class="line">9</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">10</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> init: function(config){</td></tr><tr class="miss"><td class="line">12</td><td class="hits">0</td><td class="source"> this.handle = null;</td></tr><tr class="miss"><td class="line">13</td><td class="hits">0</td><td class="source"> this.config = config;</td></tr><tr class="miss"><td class="line">14</td><td class="hits">0</td><td class="source"> this.deferred = null;</td></tr><tr class="miss"><td class="line">15</td><td class="hits">0</td><td class="source"> this.tryTimes = 0;</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> * 建立数据库连接</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> connect: function(){</td></tr><tr class="miss"><td class="line">22</td><td class="hits">0</td><td class="source"> if (this.handle) {</td></tr><tr class="miss"><td class="line">23</td><td class="hits">0</td><td class="source"> return this.deferred.promise;</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">25</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">26</td><td class="hits">0</td><td class="source"> var deferred = getDefer();</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> //创建连接</td></tr><tr class="miss"><td class="line">28</td><td class="hits">0</td><td class="source"> var connection = mysql.createConnection({</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> host : this.config.hostname || 'localhost',</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> user : this.config.username || 'root',</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> password : this.config.password || '',</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> database : this.config.database || ''</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> //连接</td></tr><tr class="miss"><td class="line">35</td><td class="hits">0</td><td class="source"> connection.connect(function(err){</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> //连接失败</td></tr><tr class="miss"><td class="line">37</td><td class="hits">0</td><td class="source"> if (err) {</td></tr><tr class="miss"><td class="line">38</td><td class="hits">0</td><td class="source"> deferred.reject(err);</td></tr><tr class="miss"><td class="line">39</td><td class="hits">0</td><td class="source"> self.close();</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">41</td><td class="hits">0</td><td class="source"> deferred.resolve();</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> //错误时关闭当前连接</td></tr><tr class="miss"><td class="line">45</td><td class="hits">0</td><td class="source"> connection.on('error', function(){</td></tr><tr class="miss"><td class="line">46</td><td class="hits">0</td><td class="source"> self.close();</td></tr><tr><td class="line">47</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> //PROTOCOL_CONNECTION_LOST</td></tr><tr class="miss"><td class="line">49</td><td class="hits">0</td><td class="source"> connection.on('end', function(){</td></tr><tr class="miss"><td class="line">50</td><td class="hits">0</td><td class="source"> self.close();</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> })</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> //连接句柄</td></tr><tr class="miss"><td class="line">53</td><td class="hits">0</td><td class="source"> this.handle = connection;</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> //把上一次的promise reject</td></tr><tr class="miss"><td class="line">55</td><td class="hits">0</td><td class="source"> if (this.deferred) {</td></tr><tr class="miss"><td class="line">56</td><td class="hits">0</td><td class="source"> this.deferred.reject(new Error('connection closed'));</td></tr><tr><td class="line">57</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">58</td><td class="hits">0</td><td class="source"> this.deferred = deferred;</td></tr><tr class="miss"><td class="line">59</td><td class="hits">0</td><td class="source"> return this.deferred.promise;</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">62</td><td class="hits"></td><td class="source"> * 查询sql语句返回一个promise</td></tr><tr><td class="line">63</td><td class="hits"></td><td class="source"> * @param {[type]} sql [description]</td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">65</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> query: function(sql){</td></tr><tr class="miss"><td class="line">67</td><td class="hits">0</td><td class="source"> if (APP_DEBUG) {</td></tr><tr class="miss"><td class="line">68</td><td class="hits">0</td><td class="source"> console.log('sql: ' + sql);</td></tr><tr><td class="line">69</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">70</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">71</td><td class="hits">0</td><td class="source"> return this.connect().then(function(){</td></tr><tr class="miss"><td class="line">72</td><td class="hits">0</td><td class="source"> var deferred = getDefer();</td></tr><tr class="miss"><td class="line">73</td><td class="hits">0</td><td class="source"> self.handle.query(sql, function(err, rows){</td></tr><tr class="miss"><td class="line">74</td><td class="hits">0</td><td class="source"> if (err) {</td></tr><tr><td class="line">75</td><td class="hits"></td><td class="source"> //当数据量非常大时,可能会出现连接丢失,这里进行重连</td></tr><tr class="miss"><td class="line">76</td><td class="hits">0</td><td class="source"> if (err.code === 'PROTOCOL_CONNECTION_LOST' &amp;&amp; self.tryTimes &lt; 3) {</td></tr><tr class="miss"><td class="line">77</td><td class="hits">0</td><td class="source"> self.tryTimes++;</td></tr><tr class="miss"><td class="line">78</td><td class="hits">0</td><td class="source"> self.close();</td></tr><tr class="miss"><td class="line">79</td><td class="hits">0</td><td class="source"> return self.query(sql);</td></tr><tr><td class="line">80</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">81</td><td class="hits">0</td><td class="source"> return deferred.reject(err);</td></tr><tr><td class="line">82</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">83</td><td class="hits">0</td><td class="source"> self.tryTimes = 0;</td></tr><tr class="miss"><td class="line">84</td><td class="hits">0</td><td class="source"> return deferred.resolve(rows || []);</td></tr><tr><td class="line">85</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">86</td><td class="hits">0</td><td class="source"> return deferred.promise;</td></tr><tr><td class="line">87</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">88</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">89</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source"> * 关闭连接</td></tr><tr><td class="line">91</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">92</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source"> close: function(){</td></tr><tr class="miss"><td class="line">94</td><td class="hits">0</td><td class="source"> if (this.handle) {</td></tr><tr class="miss"><td class="line">95</td><td class="hits">0</td><td class="source"> this.handle.destroy();</td></tr><tr class="miss"><td class="line">96</td><td class="hits">0</td><td class="source"> this.handle = null;</td></tr><tr><td class="line">97</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">98</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">99</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">100</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Template/EjsTemplate.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Driver/Template/EjsTemplate.js</h2><div id="stats" class="high"><div class="percentage">100%</div><div class="sloc">6</div><div class="hits">6</div><div class="misses">0</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * ejs</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * https://github.com/visionmedia/ejs</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> * @type {[type]}</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">var ejs = require('ejs');</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source">module.exports = {</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> fetch: function(templateFile, tVar){</td></tr><tr class="hit"><td class="line">9</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">10</td><td class="hits">1</td><td class="source"> var content = getFileContent(templateFile);</td></tr><tr class="hit"><td class="line">11</td><td class="hits">1</td><td class="source"> var conf = extend({</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> filename: templateFile,</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> cache: true</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> }, C('tpl_engine_config'));</td></tr><tr class="hit"><td class="line">15</td><td class="hits">1</td><td class="source"> return ejs.compile(content, conf)(tVar); </td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source">};</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Extend/Controller/RestController.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Extend/Controller/RestController.js</h2><div id="stats" class="high"><div class="percentage">75%</div><div class="sloc">4</div><div class="hits">3</div><div class="misses">1</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * REST Controller</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">module.exports = Controller(function(){</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> __before: function(){</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> __call: function(){</td></tr><tr class="miss"><td class="line">12</td><td class="hits">0</td><td class="source"> this.end('method is not allowed');</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source">})</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Extend/Model/AdvModel.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Extend/Model/AdvModel.js</h2><div id="stats" class="terrible"><div class="percentage">5%</div><div class="sloc">230</div><div class="hits">12</div><div class="misses">218</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * 高级模型</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">module.exports = Model(function(){</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> //关联类型</td></tr><tr class="hit"><td class="line">8</td><td class="hits">1</td><td class="source"> global.HAS_ONE = 1;</td></tr><tr class="hit"><td class="line">9</td><td class="hits">1</td><td class="source"> global.BELONGS_TO = 2;</td></tr><tr class="hit"><td class="line">10</td><td class="hits">1</td><td class="source"> global.HAS_MANY = 3;</td></tr><tr class="hit"><td class="line">11</td><td class="hits">1</td><td class="source"> global.MANY_TO_MANY = 4;</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> //post的操作类型</td></tr><tr class="hit"><td class="line">14</td><td class="hits">1</td><td class="source"> var ADD = 'ADD';</td></tr><tr class="hit"><td class="line">15</td><td class="hits">1</td><td class="source"> var UPDATE = 'UPDATE';</td></tr><tr class="hit"><td class="line">16</td><td class="hits">1</td><td class="source"> var DELETE = 'DELETE';</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> //get时不同的type对应的回调</td></tr><tr class="hit"><td class="line">19</td><td class="hits">1</td><td class="source"> var mapTypeGetFn = {</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> 1: '_getHasOneRelation',</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> 2: '_getBelongsToRelation',</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> 3: '_getHasManyRelation',</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> 4: '_getManyToManyRelation'</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> //post时不同的type对应的回调</td></tr><tr class="hit"><td class="line">27</td><td class="hits">1</td><td class="source"> var mapTypePostFn = {</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> 1: '_postHasOneRelation',</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> 2: '_postBelongsToRelation',</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> 3: '_postHasManyRelation',</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> 4: '_postManyToManyRelation'</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">34</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> * 关联定义</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> * 数据格式:</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> * 'Profile': {</td></tr><tr><td class="line">39</td><td class="hits"></td><td class="source"> type: 1,</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> model: 'Profile',</td></tr><tr><td class="line">41</td><td class="hits"></td><td class="source"> name: 'Profile',</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> key: 'id',</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> fKey: 'user_id',</td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> field: 'id,name',</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source"> where: 'name=xx',</td></tr><tr><td class="line">46</td><td class="hits"></td><td class="source"> order: '',</td></tr><tr><td class="line">47</td><td class="hits"></td><td class="source"> limit: ''</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> * }</td></tr><tr><td class="line">49</td><td class="hits"></td><td class="source"> * @type {Object}</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> relation: {},</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> * 本次使用的关联名称,默认是全部使用</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> * @type {Boolean}</td></tr><tr><td class="line">55</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">56</td><td class="hits"></td><td class="source"> _relationName: true,</td></tr><tr><td class="line">57</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">58</td><td class="hits"></td><td class="source"> * 只读字段</td></tr><tr><td class="line">59</td><td class="hits"></td><td class="source"> * @type {String}</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> readonlyField: '',</td></tr><tr><td class="line">62</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">63</td><td class="hits"></td><td class="source"> * 保存时对数据进行校验</td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> * @type {Boolean}</td></tr><tr><td class="line">65</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> _validateField: true,</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">68</td><td class="hits"></td><td class="source"> * 字段类型</td></tr><tr><td class="line">69</td><td class="hits"></td><td class="source"> * @type {Object}</td></tr><tr><td class="line">70</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">71</td><td class="hits"></td><td class="source"> fieldType: {},</td></tr><tr><td class="line">72</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">73</td><td class="hits"></td><td class="source"> * 设置本次使用的relation</td></tr><tr><td class="line">74</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">75</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">76</td><td class="hits"></td><td class="source"> setRelation: function(name, value){</td></tr><tr class="miss"><td class="line">77</td><td class="hits">0</td><td class="source"> if (isObject(name) || !isEmpty(value)) {</td></tr><tr class="miss"><td class="line">78</td><td class="hits">0</td><td class="source"> var obj = isObject(name) ? name : getObject(name, value);</td></tr><tr class="miss"><td class="line">79</td><td class="hits">0</td><td class="source"> extend(this.relation, obj);</td></tr><tr class="miss"><td class="line">80</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">81</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">82</td><td class="hits">0</td><td class="source"> if (isString(name)) {</td></tr><tr class="miss"><td class="line">83</td><td class="hits">0</td><td class="source"> name = name.split(',');</td></tr><tr><td class="line">84</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">85</td><td class="hits">0</td><td class="source"> this._relationName = name;</td></tr><tr class="miss"><td class="line">86</td><td class="hits">0</td><td class="source"> return this;</td></tr><tr><td class="line">87</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">88</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">89</td><td class="hits"></td><td class="source"> * find后置操作</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">91</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">92</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source"> _afterFind: function(data, parsedOptions){</td></tr><tr class="miss"><td class="line">94</td><td class="hits">0</td><td class="source"> return this.getRelation(data, parsedOptions);</td></tr><tr><td class="line">95</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">97</td><td class="hits"></td><td class="source"> * select后置操作</td></tr><tr><td class="line">98</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">99</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">100</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">101</td><td class="hits"></td><td class="source"> _afterSelect: function(data, parsedOptions){</td></tr><tr class="miss"><td class="line">102</td><td class="hits">0</td><td class="source"> return this.getRelation(data, parsedOptions);</td></tr><tr><td class="line">103</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">104</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">105</td><td class="hits"></td><td class="source"> * 获取关联的数据</td></tr><tr><td class="line">106</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">107</td><td class="hits"></td><td class="source"> * @param Boolean isDataList 是否是数据列表</td></tr><tr><td class="line">108</td><td class="hits"></td><td class="source"> * @return {[type]}</td></tr><tr><td class="line">109</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">110</td><td class="hits"></td><td class="source"> getRelation: function(data, parsedOptions){</td></tr><tr class="miss"><td class="line">111</td><td class="hits">0</td><td class="source"> if (isEmpty(data) || isEmpty(this.relation) || isEmpty(this._relationName)) {</td></tr><tr class="miss"><td class="line">112</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">114</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">115</td><td class="hits">0</td><td class="source"> var promises = Object.keys(this.relation).map(function(key){</td></tr><tr class="miss"><td class="line">116</td><td class="hits">0</td><td class="source"> var mapName, mapType, model, mapKey, mapfKey;</td></tr><tr class="miss"><td class="line">117</td><td class="hits">0</td><td class="source"> var value = self.relation[key];</td></tr><tr class="miss"><td class="line">118</td><td class="hits">0</td><td class="source"> if (!isObject(value)) {</td></tr><tr class="miss"><td class="line">119</td><td class="hits">0</td><td class="source"> value = {type: value};</td></tr><tr><td class="line">120</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">121</td><td class="hits">0</td><td class="source"> mapName = value.name || key;</td></tr><tr><td class="line">122</td><td class="hits"></td><td class="source"> //如果不在开启的relation内则直接返回</td></tr><tr class="miss"><td class="line">123</td><td class="hits">0</td><td class="source"> if (self._relationName !== true &amp;&amp; self._relationName.indexOf(mapName) === -1) {</td></tr><tr class="miss"><td class="line">124</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">125</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">126</td><td class="hits">0</td><td class="source"> mapType = value.type || HAS_ONE;</td></tr><tr class="miss"><td class="line">127</td><td class="hits">0</td><td class="source"> mapKey = value.key || self.getPk();</td></tr><tr class="miss"><td class="line">128</td><td class="hits">0</td><td class="source"> mapfKey = value.fKey || (self.name.toLowerCase() + '_id');</td></tr><tr class="miss"><td class="line">129</td><td class="hits">0</td><td class="source"> model = D(value.model || key);</td></tr><tr class="miss"><td class="line">130</td><td class="hits">0</td><td class="source"> model.where(value.where).cache(parsedOptions.cache).field(value.field).order(value.order).limit(value.limit);</td></tr><tr><td class="line">131</td><td class="hits"></td><td class="source"> //调用不同的类型解析</td></tr><tr class="miss"><td class="line">132</td><td class="hits">0</td><td class="source"> return self[mapTypeGetFn[mapType]](data, value, {</td></tr><tr><td class="line">133</td><td class="hits"></td><td class="source"> model: model,</td></tr><tr><td class="line">134</td><td class="hits"></td><td class="source"> mapName: mapName,</td></tr><tr><td class="line">135</td><td class="hits"></td><td class="source"> mapKey: mapKey,</td></tr><tr><td class="line">136</td><td class="hits"></td><td class="source"> mapfKey: mapfKey</td></tr><tr><td class="line">137</td><td class="hits"></td><td class="source"> }, parsedOptions);</td></tr><tr><td class="line">138</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">139</td><td class="hits">0</td><td class="source"> return Promise.all(promises).then(function(){</td></tr><tr class="miss"><td class="line">140</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">141</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">142</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">143</td><td class="hits"></td><td class="source"> _getHasOneRelation: function(data, value, mapOptions){</td></tr><tr class="miss"><td class="line">144</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">145</td><td class="hits">0</td><td class="source"> var where = self.parseRelationWhere(data, mapOptions.mapKey, mapOptions.mapfKey);</td></tr><tr class="miss"><td class="line">146</td><td class="hits">0</td><td class="source"> if (where === false) {</td></tr><tr class="miss"><td class="line">147</td><td class="hits">0</td><td class="source"> return {};</td></tr><tr><td class="line">148</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">149</td><td class="hits">0</td><td class="source"> mapOptions.model.where(where);</td></tr><tr class="miss"><td class="line">150</td><td class="hits">0</td><td class="source"> return mapOptions.model.select().then(function(mapData){</td></tr><tr class="miss"><td class="line">151</td><td class="hits">0</td><td class="source"> return self.parseRelationData(data, mapData, mapOptions.mapName, mapOptions.mapKey, mapOptions.mapfKey);</td></tr><tr><td class="line">152</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">153</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">154</td><td class="hits"></td><td class="source"> _getBelongsToRelation: function(data, value, mapOptions){</td></tr><tr class="miss"><td class="line">155</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">156</td><td class="hits">0</td><td class="source"> var mapKey, mapfKey;</td></tr><tr class="miss"><td class="line">157</td><td class="hits">0</td><td class="source"> return mapOptions.model.getTableFields().then(function(){</td></tr><tr class="miss"><td class="line">158</td><td class="hits">0</td><td class="source"> mapKey = mapOptions.model.getModelName().toLowerCase() + '_id';</td></tr><tr class="miss"><td class="line">159</td><td class="hits">0</td><td class="source"> mapfKey = mapOptions.model.getPk();</td></tr><tr class="miss"><td class="line">160</td><td class="hits">0</td><td class="source"> var where = self.parseRelationWhere(data, mapKey, mapfKey);</td></tr><tr class="miss"><td class="line">161</td><td class="hits">0</td><td class="source"> if (where === false) {</td></tr><tr class="miss"><td class="line">162</td><td class="hits">0</td><td class="source"> return {};</td></tr><tr><td class="line">163</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">164</td><td class="hits">0</td><td class="source"> mapOptions.model.where(where);</td></tr><tr class="miss"><td class="line">165</td><td class="hits">0</td><td class="source"> return mapOptions.model.select().then(function(mapData){</td></tr><tr class="miss"><td class="line">166</td><td class="hits">0</td><td class="source"> return self.parseRelationData(data, mapData, mapOptions.mapName, mapKey, mapfKey);</td></tr><tr><td class="line">167</td><td class="hits"></td><td class="source"> })</td></tr><tr><td class="line">168</td><td class="hits"></td><td class="source"> })</td></tr><tr><td class="line">169</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">170</td><td class="hits"></td><td class="source"> _getHasManyRelation: function(data, value, mapOptions){</td></tr><tr class="miss"><td class="line">171</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">172</td><td class="hits">0</td><td class="source"> var where = self.parseRelationWhere(data, mapOptions.mapKey, mapOptions.mapfKey);</td></tr><tr class="miss"><td class="line">173</td><td class="hits">0</td><td class="source"> if (where === false) {</td></tr><tr class="miss"><td class="line">174</td><td class="hits">0</td><td class="source"> return [];</td></tr><tr><td class="line">175</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">176</td><td class="hits">0</td><td class="source"> mapOptions.model.where(where);</td></tr><tr class="miss"><td class="line">177</td><td class="hits">0</td><td class="source"> return mapOptions.model.select().then(function(mapData){</td></tr><tr class="miss"><td class="line">178</td><td class="hits">0</td><td class="source"> return self.parseRelationData(data, mapData, mapOptions.mapName, mapOptions.mapKey, mapOptions.mapfKey, true);</td></tr><tr><td class="line">179</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">180</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">181</td><td class="hits"></td><td class="source"> _getManyToManyRelation: function(data, value, mapOptions, parsedOptions){</td></tr><tr class="miss"><td class="line">182</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">183</td><td class="hits">0</td><td class="source"> return mapOptions.model.getTableFields().then(function(){</td></tr><tr class="miss"><td class="line">184</td><td class="hits">0</td><td class="source"> var where = self.parseRelationWhere(data, mapOptions.mapKey, mapOptions.mapfKey);</td></tr><tr class="miss"><td class="line">185</td><td class="hits">0</td><td class="source"> if (where === false) {</td></tr><tr class="miss"><td class="line">186</td><td class="hits">0</td><td class="source"> return [];</td></tr><tr><td class="line">187</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">188</td><td class="hits">0</td><td class="source"> var whereStr = self.db.parseWhere(where);</td></tr><tr><td class="line">189</td><td class="hits"></td><td class="source"> //关联的实体表和关系表联合查询</td></tr><tr class="miss"><td class="line">190</td><td class="hits">0</td><td class="source"> var sql = 'SELECT b.%s, a.%s FROM %s as a, %s as b %s AND a.%s=b.%s %s';</td></tr><tr class="miss"><td class="line">191</td><td class="hits">0</td><td class="source"> var queryData = [</td></tr><tr><td class="line">192</td><td class="hits"></td><td class="source"> value.field || '*',</td></tr><tr><td class="line">193</td><td class="hits"></td><td class="source"> mapOptions.mapfKey,</td></tr><tr><td class="line">194</td><td class="hits"></td><td class="source"> value.rTable || self.getRelationTableName(mapOptions.model),</td></tr><tr><td class="line">195</td><td class="hits"></td><td class="source"> mapOptions.model.getTableName(),</td></tr><tr><td class="line">196</td><td class="hits"></td><td class="source"> whereStr || 'WHERE ',</td></tr><tr><td class="line">197</td><td class="hits"></td><td class="source"> value.rfKey || (mapOptions.model.getModelName().toLowerCase() + '_id'),</td></tr><tr><td class="line">198</td><td class="hits"></td><td class="source"> mapOptions.model.getPk(),</td></tr><tr><td class="line">199</td><td class="hits"></td><td class="source"> value.where ? (' AND ' + value.where) : ''</td></tr><tr><td class="line">200</td><td class="hits"></td><td class="source"> ];</td></tr><tr class="miss"><td class="line">201</td><td class="hits">0</td><td class="source"> return self.parseSql(sql, queryData).then(function(sql){</td></tr><tr class="miss"><td class="line">202</td><td class="hits">0</td><td class="source"> return self.db.select(sql, parsedOptions.cache);</td></tr><tr><td class="line">203</td><td class="hits"></td><td class="source"> }).then(function(mapData){</td></tr><tr class="miss"><td class="line">204</td><td class="hits">0</td><td class="source"> return self.parseRelationData(data, mapData, mapOptions.mapName, mapOptions.mapKey, mapOptions.mapfKey, true);</td></tr><tr><td class="line">205</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">206</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">207</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">208</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">209</td><td class="hits"></td><td class="source"> * 多对多关系下,获取对应的关联表</td></tr><tr><td class="line">210</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">211</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">212</td><td class="hits"></td><td class="source"> getRelationTableName: function(model){</td></tr><tr class="miss"><td class="line">213</td><td class="hits">0</td><td class="source"> var table = [</td></tr><tr><td class="line">214</td><td class="hits"></td><td class="source"> this.tablePrefix,</td></tr><tr><td class="line">215</td><td class="hits"></td><td class="source"> this.tableName || this.name,</td></tr><tr><td class="line">216</td><td class="hits"></td><td class="source"> '_',</td></tr><tr><td class="line">217</td><td class="hits"></td><td class="source"> model.getModelName()</td></tr><tr><td class="line">218</td><td class="hits"></td><td class="source"> ].join('');</td></tr><tr class="miss"><td class="line">219</td><td class="hits">0</td><td class="source"> return table.toLowerCase();</td></tr><tr><td class="line">220</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">221</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">222</td><td class="hits"></td><td class="source"> * 多堆垛关系下,回去对应关联表的模型</td></tr><tr><td class="line">223</td><td class="hits"></td><td class="source"> * @param {[type]} model [description]</td></tr><tr><td class="line">224</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">225</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">226</td><td class="hits"></td><td class="source"> getRelationModel: function(model){</td></tr><tr class="miss"><td class="line">227</td><td class="hits">0</td><td class="source"> var name = ucfirst(this.tableName || this.name) + ucfirst(model.getModelName());</td></tr><tr class="miss"><td class="line">228</td><td class="hits">0</td><td class="source"> return D(name);</td></tr><tr><td class="line">229</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">230</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">231</td><td class="hits"></td><td class="source"> * 解析relation的where条件</td></tr><tr><td class="line">232</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">233</td><td class="hits"></td><td class="source"> * @param {[type]} mapKey [description]</td></tr><tr><td class="line">234</td><td class="hits"></td><td class="source"> * @param {[type]} mapfKey [description]</td></tr><tr><td class="line">235</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">236</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">237</td><td class="hits"></td><td class="source"> parseRelationWhere: function(data, mapKey, mapfKey){</td></tr><tr class="miss"><td class="line">238</td><td class="hits">0</td><td class="source"> if (isArray(data)) {</td></tr><tr class="miss"><td class="line">239</td><td class="hits">0</td><td class="source"> var keys = {};</td></tr><tr class="miss"><td class="line">240</td><td class="hits">0</td><td class="source"> data.forEach(function(item){</td></tr><tr class="miss"><td class="line">241</td><td class="hits">0</td><td class="source"> keys[item[mapKey]] = 1;</td></tr><tr><td class="line">242</td><td class="hits"></td><td class="source"> })</td></tr><tr class="miss"><td class="line">243</td><td class="hits">0</td><td class="source"> var value = Object.keys(keys);</td></tr><tr class="miss"><td class="line">244</td><td class="hits">0</td><td class="source"> if (value.length === 0) {</td></tr><tr class="miss"><td class="line">245</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">246</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">247</td><td class="hits">0</td><td class="source"> return getObject(mapfKey, ['IN', value]);</td></tr><tr><td class="line">248</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">249</td><td class="hits">0</td><td class="source"> return getObject(mapfKey, data[mapKey]);</td></tr><tr><td class="line">250</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">251</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">252</td><td class="hits"></td><td class="source"> * 解析查询后的数据</td></tr><tr><td class="line">253</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">254</td><td class="hits"></td><td class="source"> * @param {[type]} mapData [description]</td></tr><tr><td class="line">255</td><td class="hits"></td><td class="source"> * @param {[type]} mapName [description]</td></tr><tr><td class="line">256</td><td class="hits"></td><td class="source"> * @param {[type]} mapKey [description]</td></tr><tr><td class="line">257</td><td class="hits"></td><td class="source"> * @param {[type]} mapfKey [description]</td></tr><tr><td class="line">258</td><td class="hits"></td><td class="source"> * @param {Boolean} isArrMap [description]</td></tr><tr><td class="line">259</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">260</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">261</td><td class="hits"></td><td class="source"> parseRelationData: function(data, mapData, mapName, mapKey, mapfKey, isArrMap){</td></tr><tr class="miss"><td class="line">262</td><td class="hits">0</td><td class="source"> if (isArray(data)) {</td></tr><tr><td class="line">263</td><td class="hits"></td><td class="source"> //提前初始化防止mapData为空导致data里的数据没有初始化的情况</td></tr><tr class="miss"><td class="line">264</td><td class="hits">0</td><td class="source"> data.forEach(function(item, i){</td></tr><tr class="miss"><td class="line">265</td><td class="hits">0</td><td class="source"> data[i][mapName] = isArrMap ? [] : {};</td></tr><tr><td class="line">266</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">267</td><td class="hits">0</td><td class="source"> mapData.forEach(function(mapItem){</td></tr><tr class="miss"><td class="line">268</td><td class="hits">0</td><td class="source"> data.forEach(function(item, i){</td></tr><tr class="miss"><td class="line">269</td><td class="hits">0</td><td class="source"> if (mapItem[mapfKey] !== item[mapKey]) {</td></tr><tr class="miss"><td class="line">270</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">271</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">272</td><td class="hits">0</td><td class="source"> if (isArrMap) {</td></tr><tr class="miss"><td class="line">273</td><td class="hits">0</td><td class="source"> data[i][mapName].push(mapItem);</td></tr><tr><td class="line">274</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">275</td><td class="hits">0</td><td class="source"> data[i][mapName] = mapItem;</td></tr><tr><td class="line">276</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">277</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">278</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">279</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">280</td><td class="hits">0</td><td class="source"> data[mapName] = isArrMap ? (mapData || []) : (mapData[0] || {});</td></tr><tr><td class="line">281</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">282</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">283</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">284</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">285</td><td class="hits"></td><td class="source"> * 添加后置操作</td></tr><tr><td class="line">286</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">287</td><td class="hits"></td><td class="source"> * @param {[type]} parsedOptions [description]</td></tr><tr><td class="line">288</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">289</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">290</td><td class="hits"></td><td class="source"> _afterAdd: function(data, parsedOptions){</td></tr><tr class="miss"><td class="line">291</td><td class="hits">0</td><td class="source"> return this.postRelation(ADD, data, parsedOptions);</td></tr><tr><td class="line">292</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">293</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">294</td><td class="hits"></td><td class="source"> * 删除后置操作</td></tr><tr><td class="line">295</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">296</td><td class="hits"></td><td class="source"> * @param {[type]} parsedOptions [description]</td></tr><tr><td class="line">297</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">298</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">299</td><td class="hits"></td><td class="source"> _afterDelete: function(data, parsedOptions){</td></tr><tr class="miss"><td class="line">300</td><td class="hits">0</td><td class="source"> return this.postRelation(DELETE, data, parsedOptions);</td></tr><tr><td class="line">301</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">302</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">303</td><td class="hits"></td><td class="source"> * 更新前置操作</td></tr><tr><td class="line">304</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">305</td><td class="hits"></td><td class="source"> * @param {[type]} parsedOptions [description]</td></tr><tr><td class="line">306</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">307</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">308</td><td class="hits"></td><td class="source"> _beforeUpdate: function(data){</td></tr><tr><td class="line">309</td><td class="hits"></td><td class="source"> //只读字段处理</td></tr><tr class="miss"><td class="line">310</td><td class="hits">0</td><td class="source"> if (!isEmpty(this.readonlyField)) {</td></tr><tr class="miss"><td class="line">311</td><td class="hits">0</td><td class="source"> if (isString(this.readonlyField)) {</td></tr><tr class="miss"><td class="line">312</td><td class="hits">0</td><td class="source"> this.readonlyField = this.readonlyField.split(',');</td></tr><tr><td class="line">313</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">314</td><td class="hits">0</td><td class="source"> this.readonlyField.forEach(function(field){</td></tr><tr class="miss"><td class="line">315</td><td class="hits">0</td><td class="source"> delete data[field];</td></tr><tr><td class="line">316</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">317</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">318</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">319</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">320</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">321</td><td class="hits"></td><td class="source"> * 更新后置操作</td></tr><tr><td class="line">322</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">323</td><td class="hits"></td><td class="source"> * @param {[type]} parsedOptions [description]</td></tr><tr><td class="line">324</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">325</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">326</td><td class="hits"></td><td class="source"> _afterUpdate: function(data, parsedOptions){</td></tr><tr class="miss"><td class="line">327</td><td class="hits">0</td><td class="source"> return this.postRelation(UPDATE, data, parsedOptions);</td></tr><tr><td class="line">328</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">329</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">330</td><td class="hits"></td><td class="source"> * 提交类关联操作</td></tr><tr><td class="line">331</td><td class="hits"></td><td class="source"> * @param {[type]} postType [description]</td></tr><tr><td class="line">332</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">333</td><td class="hits"></td><td class="source"> * @param {[type]} parsedOptions [description]</td></tr><tr><td class="line">334</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">335</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">336</td><td class="hits"></td><td class="source"> postRelation: function(postType, data, parsedOptions){</td></tr><tr class="miss"><td class="line">337</td><td class="hits">0</td><td class="source"> if (isEmpty(data) || isEmpty(this.relation) || isEmpty(this._relationName)) {</td></tr><tr class="miss"><td class="line">338</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">339</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">340</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">341</td><td class="hits">0</td><td class="source"> var promises = [];</td></tr><tr class="miss"><td class="line">342</td><td class="hits">0</td><td class="source"> Object.keys(this.relation).forEach(function(key){</td></tr><tr class="miss"><td class="line">343</td><td class="hits">0</td><td class="source"> var promise, mapName, mapType, model, mapKey, mapfKey, mapData;</td></tr><tr class="miss"><td class="line">344</td><td class="hits">0</td><td class="source"> var value = self.relation[key];</td></tr><tr class="miss"><td class="line">345</td><td class="hits">0</td><td class="source"> if (!isObject(value)) {</td></tr><tr class="miss"><td class="line">346</td><td class="hits">0</td><td class="source"> value = {type: value};</td></tr><tr><td class="line">347</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">348</td><td class="hits">0</td><td class="source"> mapName = value.name || key;</td></tr><tr><td class="line">349</td><td class="hits"></td><td class="source"> //如果没有开启对应的relation则直接返回</td></tr><tr class="miss"><td class="line">350</td><td class="hits">0</td><td class="source"> if (self._relationName !== true &amp;&amp; self._relationName.indexOf(mapName) === -1) {</td></tr><tr class="miss"><td class="line">351</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">352</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">353</td><td class="hits">0</td><td class="source"> mapData = data[mapName];</td></tr><tr><td class="line">354</td><td class="hits"></td><td class="source"> //如果没有对应的数据,则直接返回</td></tr><tr class="miss"><td class="line">355</td><td class="hits">0</td><td class="source"> if (isEmpty(mapData) &amp;&amp; postType !== DELETE) {</td></tr><tr class="miss"><td class="line">356</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">357</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">358</td><td class="hits">0</td><td class="source"> mapKey = value.key || self.getPk();</td></tr><tr class="miss"><td class="line">359</td><td class="hits">0</td><td class="source"> if (isEmpty(data[mapKey])) {</td></tr><tr class="miss"><td class="line">360</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">361</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">362</td><td class="hits">0</td><td class="source"> mapType = value.type || HAS_ONE;</td></tr><tr class="miss"><td class="line">363</td><td class="hits">0</td><td class="source"> mapfKey = value.fKey || (self.name.toLowerCase() + '_id');</td></tr><tr class="miss"><td class="line">364</td><td class="hits">0</td><td class="source"> model = D(value.model || key);</td></tr><tr class="miss"><td class="line">365</td><td class="hits">0</td><td class="source"> model.where(value.where);</td></tr><tr><td class="line">366</td><td class="hits"></td><td class="source"> //调用不同的类型解析</td></tr><tr class="miss"><td class="line">367</td><td class="hits">0</td><td class="source"> promise = self[mapTypePostFn[mapType]](data, value, {</td></tr><tr><td class="line">368</td><td class="hits"></td><td class="source"> model: model,</td></tr><tr><td class="line">369</td><td class="hits"></td><td class="source"> mapName: mapName,</td></tr><tr><td class="line">370</td><td class="hits"></td><td class="source"> mapKey: mapKey,</td></tr><tr><td class="line">371</td><td class="hits"></td><td class="source"> mapfKey: mapfKey,</td></tr><tr><td class="line">372</td><td class="hits"></td><td class="source"> mapData: mapData,</td></tr><tr><td class="line">373</td><td class="hits"></td><td class="source"> type: postType</td></tr><tr><td class="line">374</td><td class="hits"></td><td class="source"> }, parsedOptions);</td></tr><tr><td class="line">375</td><td class="hits"></td><td class="source"> </td></tr><tr class="miss"><td class="line">376</td><td class="hits">0</td><td class="source"> promises.push(promise);</td></tr><tr><td class="line">377</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">378</td><td class="hits">0</td><td class="source"> return Promise.all(promises).then(function(){</td></tr><tr class="miss"><td class="line">379</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">380</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">381</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">382</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">383</td><td class="hits"></td><td class="source"> * 一对一提交</td></tr><tr><td class="line">384</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">385</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">386</td><td class="hits"></td><td class="source"> * @param {[type]} mapOptions [description]</td></tr><tr><td class="line">387</td><td class="hits"></td><td class="source"> * @param {[type]} parsedOptions [description]</td></tr><tr><td class="line">388</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">389</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">390</td><td class="hits"></td><td class="source"> _postHasOneRelation: function(data, value, mapOptions){</td></tr><tr class="miss"><td class="line">391</td><td class="hits">0</td><td class="source"> var promise = null;</td></tr><tr class="miss"><td class="line">392</td><td class="hits">0</td><td class="source"> var where;</td></tr><tr class="miss"><td class="line">393</td><td class="hits">0</td><td class="source"> switch(mapOptions.type){</td></tr><tr><td class="line">394</td><td class="hits"></td><td class="source"> case ADD:</td></tr><tr class="miss"><td class="line">395</td><td class="hits">0</td><td class="source"> mapOptions.mapData[mapOptions.mapfKey] = data[mapOptions.mapKey];</td></tr><tr class="miss"><td class="line">396</td><td class="hits">0</td><td class="source"> promise = mapOptions.model.add(mapOptions.mapData);</td></tr><tr class="miss"><td class="line">397</td><td class="hits">0</td><td class="source"> break;</td></tr><tr><td class="line">398</td><td class="hits"></td><td class="source"> case DELETE:</td></tr><tr class="miss"><td class="line">399</td><td class="hits">0</td><td class="source"> where = getObject(mapOptions.mapfKey, data[mapOptions.mapKey]);</td></tr><tr class="miss"><td class="line">400</td><td class="hits">0</td><td class="source"> promise = mapOptions.model.where(where).delete();</td></tr><tr class="miss"><td class="line">401</td><td class="hits">0</td><td class="source"> break;</td></tr><tr><td class="line">402</td><td class="hits"></td><td class="source"> case UPDATE:</td></tr><tr class="miss"><td class="line">403</td><td class="hits">0</td><td class="source"> where = getObject(mapOptions.mapfKey, data[mapOptions.mapKey]);</td></tr><tr class="miss"><td class="line">404</td><td class="hits">0</td><td class="source"> promise = mapOptions.model.where(where).update(mapOptions.mapData);</td></tr><tr class="miss"><td class="line">405</td><td class="hits">0</td><td class="source"> break;</td></tr><tr><td class="line">406</td><td class="hits"></td><td class="source"> default:</td></tr><tr class="miss"><td class="line">407</td><td class="hits">0</td><td class="source"> break;</td></tr><tr><td class="line">408</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">409</td><td class="hits">0</td><td class="source"> return promise;</td></tr><tr><td class="line">410</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">411</td><td class="hits"></td><td class="source"> _postBelongsToRelation: function(data){</td></tr><tr class="miss"><td class="line">412</td><td class="hits">0</td><td class="source"> return data;</td></tr><tr><td class="line">413</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">414</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">415</td><td class="hits"></td><td class="source"> * 一对多提交</td></tr><tr><td class="line">416</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">417</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">418</td><td class="hits"></td><td class="source"> * @param {[type]} mapOptions [description]</td></tr><tr><td class="line">419</td><td class="hits"></td><td class="source"> * @param {[type]} parsedOptions [description]</td></tr><tr><td class="line">420</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">421</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">422</td><td class="hits"></td><td class="source"> _postHasManyRelation: function(data, value, mapOptions){</td></tr><tr class="miss"><td class="line">423</td><td class="hits">0</td><td class="source"> var type = mapOptions.type;</td></tr><tr class="miss"><td class="line">424</td><td class="hits">0</td><td class="source"> var mapData = mapOptions.mapData;</td></tr><tr class="miss"><td class="line">425</td><td class="hits">0</td><td class="source"> var model = mapOptions.model;</td></tr><tr class="miss"><td class="line">426</td><td class="hits">0</td><td class="source"> var promise;</td></tr><tr class="miss"><td class="line">427</td><td class="hits">0</td><td class="source"> if (!isArray(mapData)) {</td></tr><tr class="miss"><td class="line">428</td><td class="hits">0</td><td class="source"> mapData = [mapData];</td></tr><tr><td class="line">429</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">430</td><td class="hits">0</td><td class="source"> switch(type){</td></tr><tr><td class="line">431</td><td class="hits"></td><td class="source"> case ADD:</td></tr><tr class="miss"><td class="line">432</td><td class="hits">0</td><td class="source"> mapData = mapData.map(function(item){</td></tr><tr class="miss"><td class="line">433</td><td class="hits">0</td><td class="source"> item[mapOptions.mapfKey] = data[mapOptions.mapKey];</td></tr><tr><td class="line">434</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">435</td><td class="hits">0</td><td class="source"> promise = model.addAll(mapData);</td></tr><tr class="miss"><td class="line">436</td><td class="hits">0</td><td class="source"> break;</td></tr><tr><td class="line">437</td><td class="hits"></td><td class="source"> case UPDATE:</td></tr><tr class="miss"><td class="line">438</td><td class="hits">0</td><td class="source"> promise = model.getTableFields().then(function(){</td></tr><tr class="miss"><td class="line">439</td><td class="hits">0</td><td class="source"> var promises = [];</td></tr><tr class="miss"><td class="line">440</td><td class="hits">0</td><td class="source"> var pk = model.getPk();</td></tr><tr class="miss"><td class="line">441</td><td class="hits">0</td><td class="source"> mapData.forEach(function(item){</td></tr><tr class="miss"><td class="line">442</td><td class="hits">0</td><td class="source"> var pro;</td></tr><tr class="miss"><td class="line">443</td><td class="hits">0</td><td class="source"> if (item[pk]) {</td></tr><tr class="miss"><td class="line">444</td><td class="hits">0</td><td class="source"> pro = model.update(item);</td></tr><tr><td class="line">445</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">446</td><td class="hits">0</td><td class="source"> item[mapOptions.mapfKey] = data[mapOptions.mapKey];</td></tr><tr class="miss"><td class="line">447</td><td class="hits">0</td><td class="source"> pro = model.add(item);</td></tr><tr><td class="line">448</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">449</td><td class="hits">0</td><td class="source"> promises.push(pro);</td></tr><tr><td class="line">450</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">451</td><td class="hits">0</td><td class="source"> return Promise.all(promises);</td></tr><tr><td class="line">452</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">453</td><td class="hits">0</td><td class="source"> break;</td></tr><tr><td class="line">454</td><td class="hits"></td><td class="source"> case DELETE:</td></tr><tr class="miss"><td class="line">455</td><td class="hits">0</td><td class="source"> var where = getObject(mapOptions.mapfKey, data[mapOptions.mapKey]);</td></tr><tr class="miss"><td class="line">456</td><td class="hits">0</td><td class="source"> promise = model.where(where).delete();</td></tr><tr class="miss"><td class="line">457</td><td class="hits">0</td><td class="source"> break;</td></tr><tr><td class="line">458</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">459</td><td class="hits">0</td><td class="source"> return promise;</td></tr><tr><td class="line">460</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">461</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">462</td><td class="hits"></td><td class="source"> * 多对多提交</td></tr><tr><td class="line">463</td><td class="hits"></td><td class="source"> * @param Object data [description]</td></tr><tr><td class="line">464</td><td class="hits"></td><td class="source"> * @param object value [description]</td></tr><tr><td class="line">465</td><td class="hits"></td><td class="source"> * @param {[type]} mapOptions [description]</td></tr><tr><td class="line">466</td><td class="hits"></td><td class="source"> * @param {[type]} parsedOptions [description]</td></tr><tr><td class="line">467</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">468</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">469</td><td class="hits"></td><td class="source"> _postManyToManyRelation: function(data, value, mapOptions){</td></tr><tr class="miss"><td class="line">470</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">471</td><td class="hits">0</td><td class="source"> var model = mapOptions.model;</td></tr><tr class="miss"><td class="line">472</td><td class="hits">0</td><td class="source"> var promise = model.getTableFields();</td></tr><tr class="miss"><td class="line">473</td><td class="hits">0</td><td class="source"> var rfKey = value.rfKey || (model.getModelName().toLowerCase() + '_id');</td></tr><tr><td class="line">474</td><td class="hits"></td><td class="source"> //var relationTable = value.rTable || self.getRelationTableName(model);</td></tr><tr class="miss"><td class="line">475</td><td class="hits">0</td><td class="source"> var where;</td></tr><tr class="miss"><td class="line">476</td><td class="hits">0</td><td class="source"> var type = mapOptions.type;</td></tr><tr class="miss"><td class="line">477</td><td class="hits">0</td><td class="source"> var mapData = mapOptions.mapData;</td></tr><tr class="miss"><td class="line">478</td><td class="hits">0</td><td class="source"> var relationModel = self.getRelationModel(model);</td></tr><tr class="miss"><td class="line">479</td><td class="hits">0</td><td class="source"> if (type === DELETE || type === UPDATE) {</td></tr><tr class="miss"><td class="line">480</td><td class="hits">0</td><td class="source"> where = getObject(mapOptions.mapfKey, data[mapOptions.mapKey]);</td></tr><tr class="miss"><td class="line">481</td><td class="hits">0</td><td class="source"> promise = promise.then(function(){</td></tr><tr class="miss"><td class="line">482</td><td class="hits">0</td><td class="source"> return relationModel.where(where).delete(); </td></tr><tr><td class="line">483</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">484</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">485</td><td class="hits">0</td><td class="source"> if (type === ADD || type === UPDATE) {</td></tr><tr class="miss"><td class="line">486</td><td class="hits">0</td><td class="source"> promise = promise.then(function(){</td></tr><tr class="miss"><td class="line">487</td><td class="hits">0</td><td class="source"> if (!isArray(mapData)) {</td></tr><tr class="miss"><td class="line">488</td><td class="hits">0</td><td class="source"> mapData = isString(mapData) ? mapData.split(',') : [mapData];</td></tr><tr><td class="line">489</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">490</td><td class="hits">0</td><td class="source"> var firstItem = mapData[0];</td></tr><tr><td class="line">491</td><td class="hits"></td><td class="source"> //关系数据</td></tr><tr class="miss"><td class="line">492</td><td class="hits">0</td><td class="source"> if (isNumberString(firstItem) || (isObject(firstItem) &amp;&amp; (rfKey in firstItem))) {</td></tr><tr><td class="line">493</td><td class="hits"></td><td class="source"> //生成要更新的数据</td></tr><tr class="miss"><td class="line">494</td><td class="hits">0</td><td class="source"> var postData = mapData.map(function(item){</td></tr><tr class="miss"><td class="line">495</td><td class="hits">0</td><td class="source"> var key = [mapOptions.mapfKey, rfKey];</td></tr><tr class="miss"><td class="line">496</td><td class="hits">0</td><td class="source"> var val = [data[mapOptions.mapKey], item[rfKey] || item];</td></tr><tr class="miss"><td class="line">497</td><td class="hits">0</td><td class="source"> return getObject(key, val);</td></tr><tr><td class="line">498</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">499</td><td class="hits">0</td><td class="source"> return relationModel.addAll(postData);</td></tr><tr><td class="line">500</td><td class="hits"></td><td class="source"> }else{ //实体数据</td></tr><tr class="miss"><td class="line">501</td><td class="hits">0</td><td class="source"> var unqiueField = model.getUniqueField();</td></tr><tr class="miss"><td class="line">502</td><td class="hits">0</td><td class="source"> if (!unqiueField) {</td></tr><tr class="miss"><td class="line">503</td><td class="hits">0</td><td class="source"> return getPromise(model.getTableName() + ' table has no unqiue field', true);</td></tr><tr><td class="line">504</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">505</td><td class="hits">0</td><td class="source"> return self._getRalationAddIds(mapData, model, unqiueField).then(function(ids){</td></tr><tr class="miss"><td class="line">506</td><td class="hits">0</td><td class="source"> var postData = ids.map(function(id){</td></tr><tr class="miss"><td class="line">507</td><td class="hits">0</td><td class="source"> var key = [mapOptions.mapfKey, rfKey];</td></tr><tr class="miss"><td class="line">508</td><td class="hits">0</td><td class="source"> var val = [data[mapOptions.mapKey], id];</td></tr><tr class="miss"><td class="line">509</td><td class="hits">0</td><td class="source"> return getObject(key, val);</td></tr><tr><td class="line">510</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">511</td><td class="hits">0</td><td class="source"> return relationModel.addAll(postData);</td></tr><tr><td class="line">512</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">513</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">514</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">515</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">516</td><td class="hits">0</td><td class="source"> return promise;</td></tr><tr><td class="line">517</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">518</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">519</td><td class="hits"></td><td class="source"> * 插入数据并获取插入的id集合</td></tr><tr><td class="line">520</td><td class="hits"></td><td class="source"> * @param {[type]} dataList [description]</td></tr><tr><td class="line">521</td><td class="hits"></td><td class="source"> * @param {[type]} model [description]</td></tr><tr><td class="line">522</td><td class="hits"></td><td class="source"> * @param {[type]} unqiueField [description]</td></tr><tr><td class="line">523</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">524</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">525</td><td class="hits"></td><td class="source"> _getRalationAddIds: function(dataList, model, unqiueField){</td></tr><tr class="miss"><td class="line">526</td><td class="hits">0</td><td class="source"> var promises = [];</td></tr><tr class="miss"><td class="line">527</td><td class="hits">0</td><td class="source"> var ids = [];</td></tr><tr class="miss"><td class="line">528</td><td class="hits">0</td><td class="source"> dataList.forEach(function(item){</td></tr><tr class="miss"><td class="line">529</td><td class="hits">0</td><td class="source"> if (!isObject(item)) {</td></tr><tr class="miss"><td class="line">530</td><td class="hits">0</td><td class="source"> item = getObject(unqiueField, item);</td></tr><tr><td class="line">531</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">532</td><td class="hits">0</td><td class="source"> var value = item[unqiueField];</td></tr><tr class="miss"><td class="line">533</td><td class="hits">0</td><td class="source"> if (!value) {</td></tr><tr class="miss"><td class="line">534</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">535</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">536</td><td class="hits">0</td><td class="source"> var where = getObject(unqiueField, value);</td></tr><tr class="miss"><td class="line">537</td><td class="hits">0</td><td class="source"> var promise = model.where(where).field(model.getPk()).find().then(function(data){</td></tr><tr class="miss"><td class="line">538</td><td class="hits">0</td><td class="source"> if (isEmpty(data)) {</td></tr><tr class="miss"><td class="line">539</td><td class="hits">0</td><td class="source"> return model.add(item).then(function(insertId){</td></tr><tr class="miss"><td class="line">540</td><td class="hits">0</td><td class="source"> ids.push(insertId);</td></tr><tr><td class="line">541</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">542</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">543</td><td class="hits">0</td><td class="source"> ids.push(data[model.getPk()]);</td></tr><tr><td class="line">544</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">545</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">546</td><td class="hits">0</td><td class="source"> promises.push(promise);</td></tr><tr><td class="line">547</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">548</td><td class="hits">0</td><td class="source"> return Promise.all(promises).then(function(){</td></tr><tr class="miss"><td class="line">549</td><td class="hits">0</td><td class="source"> return ids;</td></tr><tr><td class="line">550</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">551</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">552</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">553</td><td class="hits"></td><td class="source"> * 设置是否对数据进行校验</td></tr><tr><td class="line">554</td><td class="hits"></td><td class="source"> * @param {[type]} validate [description]</td></tr><tr><td class="line">555</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">556</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">557</td><td class="hits"></td><td class="source"> validate: function(validate){</td></tr><tr class="miss"><td class="line">558</td><td class="hits">0</td><td class="source"> this._validateField = validate;</td></tr><tr><td class="line">559</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">560</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">561</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Behavior.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Behavior.js</h2><div id="stats" class="high"><div class="percentage">100%</div><div class="sloc">7</div><div class="hits">7</div><div class="misses">0</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * 行为类</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">module.exports = Class(function(){</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> options: {}, //行为选项</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> http: null,</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> init: function(http){</td></tr><tr class="hit"><td class="line">11</td><td class="hits">6</td><td class="source"> this.http = http;</td></tr><tr class="hit"><td class="line">12</td><td class="hits">6</td><td class="source"> for(var name in this.options){</td></tr><tr class="hit"><td class="line">13</td><td class="hits">10</td><td class="source"> if (C(name) !== undefined) {</td></tr><tr class="hit"><td class="line">14</td><td class="hits">9</td><td class="source"> this.options[name] = C(name);</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> run: function(){</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Cache.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Cache.js</h2><div id="stats" class="terrible"><div class="percentage">11%</div><div class="sloc">54</div><div class="hits">6</div><div class="misses">48</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * 缓存基类</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source"> * 缓存数据</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> * @type {Object}</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">9</td><td class="hits">1</td><td class="source">var cacheData = {};</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> * 定时器</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> * @type {Number}</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">14</td><td class="hits">1</td><td class="source">var gcTimer = {};</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> * 清除已经过期的Cache</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">19</td><td class="hits">1</td><td class="source">var gc = function(instance){</td></tr><tr class="miss"><td class="line">20</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">21</td><td class="hits">0</td><td class="source"> if (APP_DEBUG || APP_MODE === 'cli' || gcTimer[instance.gcType]) {</td></tr><tr class="miss"><td class="line">22</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">24</td><td class="hits">0</td><td class="source"> gcTimer[instance.gcType] = setInterval(function(){</td></tr><tr class="miss"><td class="line">25</td><td class="hits">0</td><td class="source"> var hour = (new Date()).getHours();</td></tr><tr class="miss"><td class="line">26</td><td class="hits">0</td><td class="source"> if (C('cache_gc_hour').indexOf(hour) === -1) {</td></tr><tr class="miss"><td class="line">27</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">29</td><td class="hits">0</td><td class="source"> var now = Date.now();</td></tr><tr class="miss"><td class="line">30</td><td class="hits">0</td><td class="source"> if (instance.gc) {</td></tr><tr class="miss"><td class="line">31</td><td class="hits">0</td><td class="source"> console.log('gc clean: ', instance.gcType, (new Date()).toUTCString());</td></tr><tr class="miss"><td class="line">32</td><td class="hits">0</td><td class="source"> instance.gc(now);</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> }, 3600 * 1000);</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">37</td><td class="hits">1</td><td class="source">module.exports = Class(function(){</td></tr><tr class="hit"><td class="line">38</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">39</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">41</td><td class="hits"></td><td class="source"> * gc的类型用于定时器类型判断</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> * @type {String}</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> gcType: 'Cache',</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">46</td><td class="hits"></td><td class="source"> * 初始化</td></tr><tr><td class="line">47</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">49</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> init: function(options){</td></tr><tr class="miss"><td class="line">51</td><td class="hits">0</td><td class="source"> options = options || {};</td></tr><tr class="miss"><td class="line">52</td><td class="hits">0</td><td class="source"> if (options.cacheData) {</td></tr><tr class="miss"><td class="line">53</td><td class="hits">0</td><td class="source"> this.cacheData = options.cacheData;</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">55</td><td class="hits">0</td><td class="source"> this.cacheData = cacheData;</td></tr><tr><td class="line">56</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">57</td><td class="hits">0</td><td class="source"> if (options.gcType) {</td></tr><tr class="miss"><td class="line">58</td><td class="hits">0</td><td class="source"> this.gcType = options.gcType;</td></tr><tr><td class="line">59</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">60</td><td class="hits">0</td><td class="source"> if (!options.timeout) {</td></tr><tr class="miss"><td class="line">61</td><td class="hits">0</td><td class="source"> options.timeout = C('cache_timeout')</td></tr><tr><td class="line">62</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">63</td><td class="hits">0</td><td class="source"> this.options = options;</td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> //操作的key</td></tr><tr class="miss"><td class="line">65</td><td class="hits">0</td><td class="source"> this.key = '';</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> //是否更新expire值</td></tr><tr class="miss"><td class="line">67</td><td class="hits">0</td><td class="source"> this.updateExpire = false;</td></tr><tr class="miss"><td class="line">68</td><td class="hits">0</td><td class="source"> gc(this);</td></tr><tr><td class="line">69</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">70</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">71</td><td class="hits"></td><td class="source"> * 获取缓存值返回一个promise</td></tr><tr><td class="line">72</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">73</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">74</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">75</td><td class="hits"></td><td class="source"> get: function(name){</td></tr><tr class="miss"><td class="line">76</td><td class="hits">0</td><td class="source"> var key = this.key || name;</td></tr><tr class="miss"><td class="line">77</td><td class="hits">0</td><td class="source"> if (!(key in this.cacheData)) {</td></tr><tr class="miss"><td class="line">78</td><td class="hits">0</td><td class="source"> return getPromise();</td></tr><tr><td class="line">79</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">80</td><td class="hits">0</td><td class="source"> var value = this.cacheData[key];</td></tr><tr class="miss"><td class="line">81</td><td class="hits">0</td><td class="source"> if (Date.now() &gt; value.expire) {</td></tr><tr class="miss"><td class="line">82</td><td class="hits">0</td><td class="source"> delete this.cacheData[key];</td></tr><tr class="miss"><td class="line">83</td><td class="hits">0</td><td class="source"> return getPromise();</td></tr><tr><td class="line">84</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">85</td><td class="hits">0</td><td class="source"> if (this.updateExpire) {</td></tr><tr class="miss"><td class="line">86</td><td class="hits">0</td><td class="source"> this.cacheData[key].expire = Date.now() + value.timeout * 1000;</td></tr><tr><td class="line">87</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">88</td><td class="hits">0</td><td class="source"> return getPromise(value.data[name]);</td></tr><tr><td class="line">89</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">91</td><td class="hits"></td><td class="source"> * 设置缓存值</td></tr><tr><td class="line">92</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">94</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">95</td><td class="hits"></td><td class="source"> set: function(name, value, timeout){</td></tr><tr class="miss"><td class="line">96</td><td class="hits">0</td><td class="source"> if (timeout === undefined) {</td></tr><tr class="miss"><td class="line">97</td><td class="hits">0</td><td class="source"> timeout = this.options.timeout;</td></tr><tr><td class="line">98</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">99</td><td class="hits">0</td><td class="source"> var key = this.key || name;</td></tr><tr class="miss"><td class="line">100</td><td class="hits">0</td><td class="source"> if (key in this.cacheData) {</td></tr><tr class="miss"><td class="line">101</td><td class="hits">0</td><td class="source"> this.cacheData[key].data[name] = value;</td></tr><tr><td class="line">102</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">103</td><td class="hits">0</td><td class="source"> this.cacheData[key] = {</td></tr><tr><td class="line">104</td><td class="hits"></td><td class="source"> data: getObject(name, value),</td></tr><tr><td class="line">105</td><td class="hits"></td><td class="source"> timeout: timeout,</td></tr><tr><td class="line">106</td><td class="hits"></td><td class="source"> expire: Date.now() + timeout * 1000</td></tr><tr><td class="line">107</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">108</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">109</td><td class="hits">0</td><td class="source"> return getPromise();</td></tr><tr><td class="line">110</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">111</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">112</td><td class="hits"></td><td class="source"> * 移除缓存值</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">114</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">115</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">116</td><td class="hits"></td><td class="source"> rm: function(name){</td></tr><tr class="miss"><td class="line">117</td><td class="hits">0</td><td class="source"> var key = this.key || name;</td></tr><tr class="miss"><td class="line">118</td><td class="hits">0</td><td class="source"> if (key in this.cacheData) {</td></tr><tr class="miss"><td class="line">119</td><td class="hits">0</td><td class="source"> delete this.cacheData[key].data[name];</td></tr><tr><td class="line">120</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">121</td><td class="hits">0</td><td class="source"> return getPromise();</td></tr><tr><td class="line">122</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">123</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">124</td><td class="hits"></td><td class="source"> * gc</td></tr><tr><td class="line">125</td><td class="hits"></td><td class="source"> * @param {[type]} now [description]</td></tr><tr><td class="line">126</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">127</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">128</td><td class="hits"></td><td class="source"> gc: function(now){</td></tr><tr class="miss"><td class="line">129</td><td class="hits">0</td><td class="source"> for(var key in this.cacheData){</td></tr><tr class="miss"><td class="line">130</td><td class="hits">0</td><td class="source"> var item = this.cacheData[key] || {};</td></tr><tr class="miss"><td class="line">131</td><td class="hits">0</td><td class="source"> if (now &gt; item.expire) {</td></tr><tr class="miss"><td class="line">132</td><td class="hits">0</td><td class="source"> delete this.cacheData[key];</td></tr><tr><td class="line">133</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">134</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">135</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">136</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">137</td><td class="hits"></td><td class="source">});</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Cookie.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Cookie.js</h2><div id="stats" class="terrible"><div class="percentage">22%</div><div class="sloc">35</div><div class="hits">8</div><div class="misses">27</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * cookie操作</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @type {Object}</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">module.exports = {</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> * 解析</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> * @param {[type]} str [description]</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> parse: function(str){</td></tr><tr class="hit"><td class="line">12</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">13</td><td class="hits">1</td><td class="source"> var data = {};</td></tr><tr class="hit"><td class="line">14</td><td class="hits">1</td><td class="source"> str.split(/[;,] */).forEach(function(item) {</td></tr><tr class="hit"><td class="line">15</td><td class="hits">1</td><td class="source"> var pos = item.indexOf('=');</td></tr><tr class="hit"><td class="line">16</td><td class="hits">1</td><td class="source"> if (pos === -1) {</td></tr><tr class="hit"><td class="line">17</td><td class="hits">1</td><td class="source"> return;</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">19</td><td class="hits">0</td><td class="source"> var key = item.substr(0, pos).trim();</td></tr><tr class="miss"><td class="line">20</td><td class="hits">0</td><td class="source"> var val = item.substr(++pos, item.length).trim();</td></tr><tr class="miss"><td class="line">21</td><td class="hits">0</td><td class="source"> if ('&quot;' === val[0]) {</td></tr><tr class="miss"><td class="line">22</td><td class="hits">0</td><td class="source"> val = val.slice(1, -1);</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> // only assign once</td></tr><tr class="miss"><td class="line">25</td><td class="hits">0</td><td class="source"> if (undefined === data[key]) {</td></tr><tr class="miss"><td class="line">26</td><td class="hits">0</td><td class="source"> try {</td></tr><tr class="miss"><td class="line">27</td><td class="hits">0</td><td class="source"> data[key] = decodeURIComponent(val);</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> } catch (e) {</td></tr><tr class="miss"><td class="line">29</td><td class="hits">0</td><td class="source"> data[key] = val;</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> });</td></tr><tr class="hit"><td class="line">33</td><td class="hits">1</td><td class="source"> return data;</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> * 格式化</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> * @param {[type]} name [description]</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> * @param {[type]} val [description]</td></tr><tr><td class="line">39</td><td class="hits"></td><td class="source"> * @param {[type]} options [description]</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">41</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> stringify: function(name, value, options){</td></tr><tr class="miss"><td class="line">43</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">44</td><td class="hits">0</td><td class="source"> options = options || {};</td></tr><tr class="miss"><td class="line">45</td><td class="hits">0</td><td class="source"> var item = [name + '=' + encodeURIComponent(value)];</td></tr><tr class="miss"><td class="line">46</td><td class="hits">0</td><td class="source"> if (options.maxage) {</td></tr><tr class="miss"><td class="line">47</td><td class="hits">0</td><td class="source"> item.push('Max-Age=' + options.maxage);</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">49</td><td class="hits">0</td><td class="source"> if (options.domain) {</td></tr><tr class="miss"><td class="line">50</td><td class="hits">0</td><td class="source"> item.push('Domain=' + options.domain);</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">52</td><td class="hits">0</td><td class="source"> if (options.path) {</td></tr><tr class="miss"><td class="line">53</td><td class="hits">0</td><td class="source"> item.push('Path=' + options.path);</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">55</td><td class="hits">0</td><td class="source"> var expires = options.expires;</td></tr><tr class="miss"><td class="line">56</td><td class="hits">0</td><td class="source"> if (expires){</td></tr><tr class="miss"><td class="line">57</td><td class="hits">0</td><td class="source"> if (!isDate(expires)) {</td></tr><tr class="miss"><td class="line">58</td><td class="hits">0</td><td class="source"> expires = new Date(expires);</td></tr><tr><td class="line">59</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">60</td><td class="hits">0</td><td class="source"> item.push('Expires=' + expires.toUTCString());</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> } </td></tr><tr class="miss"><td class="line">62</td><td class="hits">0</td><td class="source"> if (options.httponly) {</td></tr><tr class="miss"><td class="line">63</td><td class="hits">0</td><td class="source"> item.push('HttpOnly');</td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">65</td><td class="hits">0</td><td class="source"> if (options.secure) {</td></tr><tr class="miss"><td class="line">66</td><td class="hits">0</td><td class="source"> item.push('Secure');</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">68</td><td class="hits">0</td><td class="source"> return item.join('; ');</td></tr><tr><td class="line">69</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">70</td><td class="hits"></td><td class="source">}</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Filter.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Filter.js</h2><div id="stats" class="terrible"><div class="percentage">3%</div><div class="sloc">54</div><div class="hits">2</div><div class="misses">52</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * 过滤器</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">var Filter = module.exports = {</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">7</td><td class="hits"></td><td class="source"> * 分页</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> page: function(value){</td></tr><tr class="miss"><td class="line">12</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">13</td><td class="hits">0</td><td class="source"> return this.id(value) || 1;</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> * xxx asc,yyy desc</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> order: function(value){</td></tr><tr class="miss"><td class="line">20</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">21</td><td class="hits">0</td><td class="source"> if (isString(value)) {</td></tr><tr class="miss"><td class="line">22</td><td class="hits">0</td><td class="source"> value = value.split(',');</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">24</td><td class="hits">0</td><td class="source"> if (!isArray(value)) {</td></tr><tr class="miss"><td class="line">25</td><td class="hits">0</td><td class="source"> return '';</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">27</td><td class="hits">0</td><td class="source"> return value.filter(function(item){</td></tr><tr class="miss"><td class="line">28</td><td class="hits">0</td><td class="source"> item = item.trim().split(' ');</td></tr><tr class="miss"><td class="line">29</td><td class="hits">0</td><td class="source"> var field = item[0];</td></tr><tr class="miss"><td class="line">30</td><td class="hits">0</td><td class="source"> var type = item[1];</td></tr><tr class="miss"><td class="line">31</td><td class="hits">0</td><td class="source"> if (/^(ASC|DESC)$/i.test(type) &amp;&amp; /^[\w]+$/.test(field)) {</td></tr><tr class="miss"><td class="line">32</td><td class="hits">0</td><td class="source"> return field + ' ' + type;</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> }).join(',');</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> * 大于0</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">39</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> id: function(value){</td></tr><tr class="miss"><td class="line">41</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">42</td><td class="hits">0</td><td class="source"> value = parseInt(value + '', 10);</td></tr><tr class="miss"><td class="line">43</td><td class="hits">0</td><td class="source"> if (value &gt; 0) {</td></tr><tr class="miss"><td class="line">44</td><td class="hits">0</td><td class="source"> return value;</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">46</td><td class="hits">0</td><td class="source"> return 0;</td></tr><tr><td class="line">47</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">49</td><td class="hits"></td><td class="source"> * id列表</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> ids: function(value, split){</td></tr><tr class="miss"><td class="line">53</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">54</td><td class="hits">0</td><td class="source"> if (isNumber(value)) {</td></tr><tr class="miss"><td class="line">55</td><td class="hits">0</td><td class="source"> value = this.id(value);</td></tr><tr class="miss"><td class="line">56</td><td class="hits">0</td><td class="source"> if (value) {</td></tr><tr class="miss"><td class="line">57</td><td class="hits">0</td><td class="source"> return [value];</td></tr><tr><td class="line">58</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">59</td><td class="hits">0</td><td class="source"> return [];</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">61</td><td class="hits">0</td><td class="source"> if (isString(value)) {</td></tr><tr class="miss"><td class="line">62</td><td class="hits">0</td><td class="source"> value = value.split(split || ',');</td></tr><tr><td class="line">63</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">64</td><td class="hits">0</td><td class="source"> if (!isArray(value)) {</td></tr><tr class="miss"><td class="line">65</td><td class="hits">0</td><td class="source"> return [];</td></tr><tr><td class="line">66</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">67</td><td class="hits">0</td><td class="source"> return value.filter(function(item){</td></tr><tr class="miss"><td class="line">68</td><td class="hits">0</td><td class="source"> item = (item + '').trim();</td></tr><tr class="miss"><td class="line">69</td><td class="hits">0</td><td class="source"> item = parseInt(item, 10);</td></tr><tr class="miss"><td class="line">70</td><td class="hits">0</td><td class="source"> return item;</td></tr><tr><td class="line">71</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">72</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">73</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">74</td><td class="hits"></td><td class="source"> * 是否在一个中</td></tr><tr><td class="line">75</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">76</td><td class="hits"></td><td class="source"> * @param {[type]} arr [description]</td></tr><tr><td class="line">77</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">78</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">79</td><td class="hits"></td><td class="source"> in: function(value, arr){</td></tr><tr class="miss"><td class="line">80</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">81</td><td class="hits">0</td><td class="source"> if (!isArray(arr)) {</td></tr><tr class="miss"><td class="line">82</td><td class="hits">0</td><td class="source"> arr = [arr];</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">84</td><td class="hits">0</td><td class="source"> if(arr.indexOf(value) &gt; -1){</td></tr><tr class="miss"><td class="line">85</td><td class="hits">0</td><td class="source"> return value;</td></tr><tr><td class="line">86</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">87</td><td class="hits">0</td><td class="source"> return '';</td></tr><tr><td class="line">88</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">89</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source"> * 将字符串切割为数组</td></tr><tr><td class="line">91</td><td class="hits"></td><td class="source"> * @param {[type]} value [description]</td></tr><tr><td class="line">92</td><td class="hits"></td><td class="source"> * @param {[type]} split [description]</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">94</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">95</td><td class="hits"></td><td class="source"> strs: function(value, split){</td></tr><tr class="miss"><td class="line">96</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">97</td><td class="hits">0</td><td class="source"> if (isString(value)) {</td></tr><tr class="miss"><td class="line">98</td><td class="hits">0</td><td class="source"> value = value.split(split || ',');</td></tr><tr><td class="line">99</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">100</td><td class="hits">0</td><td class="source"> if (!isArray(value)) {</td></tr><tr class="miss"><td class="line">101</td><td class="hits">0</td><td class="source"> return [];</td></tr><tr><td class="line">102</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">103</td><td class="hits">0</td><td class="source"> return value.filter(function(item){</td></tr><tr class="miss"><td class="line">104</td><td class="hits">0</td><td class="source"> return (item + '').trim();</td></tr><tr><td class="line">105</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">106</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">107</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">108</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">109</td><td class="hits"></td><td class="source"> * 调用一个过滤器</td></tr><tr><td class="line">110</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">111</td><td class="hits"></td><td class="source"> * @param {[type]} type [description]</td></tr><tr><td class="line">112</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">114</td><td class="hits">1</td><td class="source">Filter.filter = function(value, type){</td></tr><tr class="miss"><td class="line">115</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">116</td><td class="hits">0</td><td class="source"> var fn = Filter[type];</td></tr><tr class="miss"><td class="line">117</td><td class="hits">0</td><td class="source"> if (typeof fn === 'function') {</td></tr><tr class="miss"><td class="line">118</td><td class="hits">0</td><td class="source"> var args = [].slice.call(arguments, 2);</td></tr><tr class="miss"><td class="line">119</td><td class="hits">0</td><td class="source"> args.unshift(value);</td></tr><tr class="miss"><td class="line">120</td><td class="hits">0</td><td class="source"> return Filter[type].apply(Filter, args);</td></tr><tr><td class="line">121</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">122</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">123</td><td class="hits"></td><td class="source">};</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Session.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Session.js</h2><div id="stats" class="terrible"><div class="percentage">16%</div><div class="sloc">50</div><div class="hits">8</div><div class="misses">42</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"><td class="line">1</td><td class="hits">1</td><td class="source">var crypto = require('crypto');</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * 生成uid</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> * @param int length</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> * @return string</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source">var uid = function(length){</td></tr><tr class="miss"><td class="line">8</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">9</td><td class="hits">0</td><td class="source"> var ratio = Math.log(64) / Math.log(256);</td></tr><tr class="miss"><td class="line">10</td><td class="hits">0</td><td class="source"> var numbytes = Math.ceil(length * ratio);</td></tr><tr class="miss"><td class="line">11</td><td class="hits">0</td><td class="source"> var str = crypto.randomBytes(numbytes).toString('base64').slice(0, length);</td></tr><tr class="miss"><td class="line">12</td><td class="hits">0</td><td class="source"> return str.replace(/\+/g, '_').replace(/\//g, '-');</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> * 生成cookie签名</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> * @param string val</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> * @param string secret</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> * @return string</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">20</td><td class="hits">1</td><td class="source">var cookieSign = function(val, secret){</td></tr><tr class="miss"><td class="line">21</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">22</td><td class="hits">0</td><td class="source"> secret = crypto.createHmac('sha256', secret).update(val).digest('base64');</td></tr><tr class="miss"><td class="line">23</td><td class="hits">0</td><td class="source"> secret = secret.replace(/\=+$/, '');</td></tr><tr class="miss"><td class="line">24</td><td class="hits">0</td><td class="source"> return val + '.' + secret;</td></tr><tr><td class="line">25</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">26</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> * 解析cookie签名</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> * @param {[type]} val</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> * @param {[type]} secret</td></tr><tr><td class="line">30</td><td class="hits"></td><td class="source"> * @return {[type]}</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">32</td><td class="hits">1</td><td class="source">var cookieUnsign = function(val, secret){</td></tr><tr class="miss"><td class="line">33</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">34</td><td class="hits">0</td><td class="source"> var str = val.slice(0, val.lastIndexOf('.'));</td></tr><tr class="miss"><td class="line">35</td><td class="hits">0</td><td class="source"> return cookieSign(str, secret) === val ? str : false;</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source">};</td></tr><tr><td class="line">37</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">38</td><td class="hits">1</td><td class="source">var Session = module.exports = Cache(function(){</td></tr><tr class="hit"><td class="line">39</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">40</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">41</td><td class="hits"></td><td class="source"> init: function(options){</td></tr><tr class="miss"><td class="line">42</td><td class="hits">0</td><td class="source"> this.super_('init', options);</td></tr><tr class="miss"><td class="line">43</td><td class="hits">0</td><td class="source"> this.key = this.options.cookie;</td></tr><tr class="miss"><td class="line">44</td><td class="hits">0</td><td class="source"> this.updateExpire = true;</td></tr><tr><td class="line">45</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">46</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">47</td><td class="hits"></td><td class="source">});</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">49</td><td class="hits">1</td><td class="source">Session.start = function(http){</td></tr><tr class="miss"><td class="line">50</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">51</td><td class="hits">0</td><td class="source"> if (http.session) {</td></tr><tr class="miss"><td class="line">52</td><td class="hits">0</td><td class="source"> return http.session;</td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">54</td><td class="hits">0</td><td class="source"> var name = C('session_name');</td></tr><tr><td class="line">55</td><td class="hits"></td><td class="source"> //是否使用签名</td></tr><tr class="miss"><td class="line">56</td><td class="hits">0</td><td class="source"> var secret = C('session_sign');</td></tr><tr class="miss"><td class="line">57</td><td class="hits">0</td><td class="source"> var cookie = http.cookie[name];</td></tr><tr class="miss"><td class="line">58</td><td class="hits">0</td><td class="source"> if (cookie &amp;&amp; secret) {</td></tr><tr class="miss"><td class="line">59</td><td class="hits">0</td><td class="source"> cookie = cookieUnsign(cookie, secret);</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">61</td><td class="hits">0</td><td class="source"> var session_cookie = cookie;</td></tr><tr class="miss"><td class="line">62</td><td class="hits">0</td><td class="source"> if (!cookie) {</td></tr><tr class="miss"><td class="line">63</td><td class="hits">0</td><td class="source"> cookie = uid(32);</td></tr><tr class="miss"><td class="line">64</td><td class="hits">0</td><td class="source"> session_cookie = cookie;</td></tr><tr class="miss"><td class="line">65</td><td class="hits">0</td><td class="source"> if (secret) {</td></tr><tr class="miss"><td class="line">66</td><td class="hits">0</td><td class="source"> cookie = cookieSign(cookie, secret);</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">68</td><td class="hits">0</td><td class="source"> http.setCookie(name, cookie, C('session_options'));</td></tr><tr><td class="line">69</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">70</td><td class="hits">0</td><td class="source"> var type = C('session_type');</td></tr><tr class="miss"><td class="line">71</td><td class="hits">0</td><td class="source"> if (!type &amp;&amp; APP_DEBUG) {</td></tr><tr class="miss"><td class="line">72</td><td class="hits">0</td><td class="source"> type = 'File';</td></tr><tr class="miss"><td class="line">73</td><td class="hits">0</td><td class="source"> console.log(&quot;in debug mode, session can't use memory type for storage, convert to File type&quot;);</td></tr><tr><td class="line">74</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">75</td><td class="hits"></td><td class="source"> //使用cluster的时候不能使用内存来缓存Session</td></tr><tr class="miss"><td class="line">76</td><td class="hits">0</td><td class="source"> if (!type &amp;&amp; C('use_cluster')) {</td></tr><tr class="miss"><td class="line">77</td><td class="hits">0</td><td class="source"> type = 'File';</td></tr><tr class="miss"><td class="line">78</td><td class="hits">0</td><td class="source"> console.log(&quot;in cluster mode, session can't use memory type for storage, convert to File type&quot;)</td></tr><tr><td class="line">79</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">80</td><td class="hits">0</td><td class="source"> name = type + 'Session';</td></tr><tr><td class="line">81</td><td class="hits"></td><td class="source"> //session类</td></tr><tr class="miss"><td class="line">82</td><td class="hits">0</td><td class="source"> var session = http.session = thinkRequire(name)({</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> cookie: session_cookie,</td></tr><tr><td class="line">84</td><td class="hits"></td><td class="source"> timeout: C('session_timeout')</td></tr><tr><td class="line">85</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">86</td><td class="hits"></td><td class="source"> //afterend时刷新缓存</td></tr><tr class="miss"><td class="line">87</td><td class="hits">0</td><td class="source"> http.on('afterEnd', function(){</td></tr><tr><td class="line">88</td><td class="hits"></td><td class="source"> //刷新session</td></tr><tr class="miss"><td class="line">89</td><td class="hits">0</td><td class="source"> return session.flush &amp;&amp; session.flush();</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source"> })</td></tr><tr class="miss"><td class="line">91</td><td class="hits">0</td><td class="source"> return cookie;</td></tr><tr><td class="line">92</td><td class="hits"></td><td class="source">};</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Valid.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/Valid.js</h2><div id="stats" class="terrible"><div class="percentage">7%</div><div class="sloc">70</div><div class="hits">5</div><div class="misses">65</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class="line">1</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">2</td><td class="hits"></td><td class="source"> * Valid类</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">var net = require('net');</td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">var Valid = module.exports = Class(function(){</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr class="hit"><td class="line">8</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> field: '',</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> init: function(field){</td></tr><tr class="miss"><td class="line">11</td><td class="hits">0</td><td class="source"> this.field = field;</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">13</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> * 长度区域</td></tr><tr><td class="line">15</td><td class="hits"></td><td class="source"> * @param {[type]} min [description]</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source"> * @param {[type]} max [description]</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> length: function(min, max){</td></tr><tr class="miss"><td class="line">20</td><td class="hits">0</td><td class="source"> min = min | 0;</td></tr><tr class="miss"><td class="line">21</td><td class="hits">0</td><td class="source"> var length = this.field.length;</td></tr><tr class="miss"><td class="line">22</td><td class="hits">0</td><td class="source"> if (length &lt; min) {</td></tr><tr class="miss"><td class="line">23</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">24</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">25</td><td class="hits">0</td><td class="source"> if (max) {</td></tr><tr class="miss"><td class="line">26</td><td class="hits">0</td><td class="source"> if (length &gt; max) {</td></tr><tr class="miss"><td class="line">27</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">28</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">29</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">30</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">31</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">32</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">33</td><td class="hits"></td><td class="source"> * 必填</td></tr><tr><td class="line">34</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">35</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> required: function(){</td></tr><tr class="miss"><td class="line">37</td><td class="hits">0</td><td class="source"> return (this.field + '').length &gt; 0;</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">39</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> * 自定义正则校验</td></tr><tr><td class="line">41</td><td class="hits"></td><td class="source"> * @param {[type]} reg [description]</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> regexp: function(reg){</td></tr><tr class="miss"><td class="line">45</td><td class="hits">0</td><td class="source"> return reg.test(this.field);</td></tr><tr><td class="line">46</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">47</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">48</td><td class="hits"></td><td class="source"> * 邮箱</td></tr><tr><td class="line">49</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">50</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> email: function(){</td></tr><tr class="miss"><td class="line">52</td><td class="hits">0</td><td class="source"> return this.regexp(/^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/);</td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">55</td><td class="hits"></td><td class="source"> * 时间戳</td></tr><tr><td class="line">56</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">57</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">58</td><td class="hits"></td><td class="source"> time: function(){</td></tr><tr class="miss"><td class="line">59</td><td class="hits">0</td><td class="source"> return this.regexp(/^(([0-1]\d)|(2[0-3])):[0-5]\d:[0-5]\d$/);</td></tr><tr><td class="line">60</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">62</td><td class="hits"></td><td class="source"> * 中文名</td></tr><tr><td class="line">63</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">64</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">65</td><td class="hits"></td><td class="source"> cnname: function(){</td></tr><tr class="miss"><td class="line">66</td><td class="hits">0</td><td class="source"> return this.regexp(/^[\u4e00-\u9fa5a-zA-Z.\u3002\u2022]{2,32}$/);</td></tr><tr><td class="line">67</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">68</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">69</td><td class="hits"></td><td class="source"> * 身份证号码</td></tr><tr><td class="line">70</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">71</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">72</td><td class="hits"></td><td class="source"> idnumber: function(){</td></tr><tr class="miss"><td class="line">73</td><td class="hits">0</td><td class="source"> if (/^\d{15}$/.test(this.field)) {</td></tr><tr class="miss"><td class="line">74</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">75</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">76</td><td class="hits">0</td><td class="source"> if ((/^\d{17}[0-9xX]$/).test(this.field)) {</td></tr><tr class="miss"><td class="line">77</td><td class="hits">0</td><td class="source"> var vs = '1,0,x,9,8,7,6,5,4,3,2'.split(','),</td></tr><tr><td class="line">78</td><td class="hits"></td><td class="source"> ps = '7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2'.split(','),</td></tr><tr><td class="line">79</td><td class="hits"></td><td class="source"> ss = this.field.toLowerCase().split(''),</td></tr><tr><td class="line">80</td><td class="hits"></td><td class="source"> r = 0;</td></tr><tr class="miss"><td class="line">81</td><td class="hits">0</td><td class="source"> for (var i = 0; i &lt; 17; i++) {</td></tr><tr class="miss"><td class="line">82</td><td class="hits">0</td><td class="source"> r += ps[i] * ss[i];</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">84</td><td class="hits">0</td><td class="source"> var isOk = (vs[r % 11] === ss[17]);</td></tr><tr class="miss"><td class="line">85</td><td class="hits">0</td><td class="source"> return isOk;</td></tr><tr><td class="line">86</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">87</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">88</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">89</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source"> * 手机号</td></tr><tr><td class="line">91</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">92</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source"> mobile: function(){</td></tr><tr class="miss"><td class="line">94</td><td class="hits">0</td><td class="source"> return this.regexp(/^(13|15|18|14)\d{9}$/);</td></tr><tr><td class="line">95</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">97</td><td class="hits"></td><td class="source"> * 邮编</td></tr><tr><td class="line">98</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">99</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">100</td><td class="hits"></td><td class="source"> zipcode: function(){</td></tr><tr class="miss"><td class="line">101</td><td class="hits">0</td><td class="source"> return this.regexp(/^\d{6}$/);</td></tr><tr><td class="line">102</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">103</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">104</td><td class="hits"></td><td class="source"> * 2次值是否一致</td></tr><tr><td class="line">105</td><td class="hits"></td><td class="source"> * @param {[type]} field [description]</td></tr><tr><td class="line">106</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">107</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">108</td><td class="hits"></td><td class="source"> confirm: function(field){</td></tr><tr class="miss"><td class="line">109</td><td class="hits">0</td><td class="source"> return this.field === field;</td></tr><tr><td class="line">110</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">111</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">112</td><td class="hits"></td><td class="source"> * url</td></tr><tr><td class="line">113</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">114</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">115</td><td class="hits"></td><td class="source"> url: function(){</td></tr><tr class="miss"><td class="line">116</td><td class="hits">0</td><td class="source"> return this.regexp(/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(?:[\/\?#][\/=\?%\-&amp;~`@[\]\':+!\.#\w]*)?$/);</td></tr><tr><td class="line">117</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">118</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">119</td><td class="hits"></td><td class="source"> * 整数</td></tr><tr><td class="line">120</td><td class="hits"></td><td class="source"> * @param {[type]} o [description]</td></tr><tr><td class="line">121</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">122</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">123</td><td class="hits"></td><td class="source"> int: function(){</td></tr><tr class="miss"><td class="line">124</td><td class="hits">0</td><td class="source"> var value = parseInt(this.field, 0 || 10);</td></tr><tr class="miss"><td class="line">125</td><td class="hits">0</td><td class="source"> if (isNaN(value)) {</td></tr><tr class="miss"><td class="line">126</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">127</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">128</td><td class="hits">0</td><td class="source"> return (value + '').length === this.field.length;</td></tr><tr><td class="line">129</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">130</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">131</td><td class="hits"></td><td class="source"> * 浮点数</td></tr><tr><td class="line">132</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">133</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">134</td><td class="hits"></td><td class="source"> float: function(){</td></tr><tr class="miss"><td class="line">135</td><td class="hits">0</td><td class="source"> var value = parseFloat(this.field);</td></tr><tr class="miss"><td class="line">136</td><td class="hits">0</td><td class="source"> if (isNaN(value)) {</td></tr><tr class="miss"><td class="line">137</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">138</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">139</td><td class="hits">0</td><td class="source"> return (value + '').length === this.field.length;</td></tr><tr><td class="line">140</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">141</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">142</td><td class="hits"></td><td class="source"> * 整数范围</td></tr><tr><td class="line">143</td><td class="hits"></td><td class="source"> * @param {[type]} min [description]</td></tr><tr><td class="line">144</td><td class="hits"></td><td class="source"> * @param {[type]} max [description]</td></tr><tr><td class="line">145</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">146</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">147</td><td class="hits"></td><td class="source"> range: function(min, max){</td></tr><tr class="miss"><td class="line">148</td><td class="hits">0</td><td class="source"> var isInt = this.int();</td></tr><tr class="miss"><td class="line">149</td><td class="hits">0</td><td class="source"> if (!isInt) {</td></tr><tr class="miss"><td class="line">150</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">151</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">152</td><td class="hits">0</td><td class="source"> return this.field &gt;= min &amp;&amp; this.field &lt;= max;</td></tr><tr><td class="line">153</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">154</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">155</td><td class="hits"></td><td class="source"> * ip4校验</td></tr><tr><td class="line">156</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">157</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">158</td><td class="hits"></td><td class="source"> ip4: function(){</td></tr><tr class="miss"><td class="line">159</td><td class="hits">0</td><td class="source"> return net.isIPv4(this.field);</td></tr><tr><td class="line">160</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">161</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">162</td><td class="hits"></td><td class="source"> * ip6校验</td></tr><tr><td class="line">163</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">164</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">165</td><td class="hits"></td><td class="source"> ip6: function(){</td></tr><tr class="miss"><td class="line">166</td><td class="hits">0</td><td class="source"> return net.isIPv6(this.field);</td></tr><tr><td class="line">167</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">168</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">169</td><td class="hits"></td><td class="source"> * ip校验</td></tr><tr><td class="line">170</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">171</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">172</td><td class="hits"></td><td class="source"> ip: function(){</td></tr><tr class="miss"><td class="line">173</td><td class="hits">0</td><td class="source"> return net.isIP(this.field);</td></tr><tr><td class="line">174</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">175</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">176</td><td class="hits"></td><td class="source"> * 日期校验</td></tr><tr><td class="line">177</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">178</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">179</td><td class="hits"></td><td class="source"> date: function(){</td></tr><tr class="miss"><td class="line">180</td><td class="hits">0</td><td class="source"> var reg = /^\d{4}-\d{1,2}-\d{1,2}$/;</td></tr><tr class="miss"><td class="line">181</td><td class="hits">0</td><td class="source"> return this.regexp(reg);</td></tr><tr><td class="line">182</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">183</td><td class="hits"></td><td class="source"> };</td></tr><tr><td class="line">184</td><td class="hits"></td><td class="source">});</td></tr><tr><td class="line">185</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">186</td><td class="hits"></td><td class="source"> * data格式</td></tr><tr><td class="line">187</td><td class="hits"></td><td class="source"> * [{</td></tr><tr><td class="line">188</td><td class="hits"></td><td class="source"> * value: xxx,</td></tr><tr><td class="line">189</td><td class="hits"></td><td class="source"> * name: '',</td></tr><tr><td class="line">190</td><td class="hits"></td><td class="source"> * valid: ['required', 'range'],</td></tr><tr><td class="line">191</td><td class="hits"></td><td class="source"> * range_args: [],</td></tr><tr><td class="line">192</td><td class="hits"></td><td class="source"> * msg:{</td></tr><tr><td class="line">193</td><td class="hits"></td><td class="source"> * required: '',</td></tr><tr><td class="line">194</td><td class="hits"></td><td class="source"> * range: ''</td></tr><tr><td class="line">195</td><td class="hits"></td><td class="source"> * }</td></tr><tr><td class="line">196</td><td class="hits"></td><td class="source"> * },{</td></tr><tr><td class="line">197</td><td class="hits"></td><td class="source"> * value: xxx,</td></tr><tr><td class="line">198</td><td class="hits"></td><td class="source"> * name: '',</td></tr><tr><td class="line">199</td><td class="hits"></td><td class="source"> * valid: ['required', 'range'],</td></tr><tr><td class="line">200</td><td class="hits"></td><td class="source"> * range_args: [],</td></tr><tr><td class="line">201</td><td class="hits"></td><td class="source"> * msg:{</td></tr><tr><td class="line">202</td><td class="hits"></td><td class="source"> * required: '',</td></tr><tr><td class="line">203</td><td class="hits"></td><td class="source"> * range: ''</td></tr><tr><td class="line">204</td><td class="hits"></td><td class="source"> * }</td></tr><tr><td class="line">205</td><td class="hits"></td><td class="source"> * }]</td></tr><tr><td class="line">206</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">207</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">208</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">209</td><td class="hits">1</td><td class="source">Valid.check = function(data){</td></tr><tr class="miss"><td class="line">210</td><td class="hits">0</td><td class="source"> 'use strict';</td></tr><tr class="miss"><td class="line">211</td><td class="hits">0</td><td class="source"> data = data ||[];</td></tr><tr class="miss"><td class="line">212</td><td class="hits">0</td><td class="source"> var result = {};</td></tr><tr class="miss"><td class="line">213</td><td class="hits">0</td><td class="source"> data.forEach(function(item){</td></tr><tr class="miss"><td class="line">214</td><td class="hits">0</td><td class="source"> var valid = item.valid;</td></tr><tr class="miss"><td class="line">215</td><td class="hits">0</td><td class="source"> if (!isArray(valid)) {</td></tr><tr class="miss"><td class="line">216</td><td class="hits">0</td><td class="source"> valid = [valid];</td></tr><tr><td class="line">217</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">218</td><td class="hits">0</td><td class="source"> var instance = Valid(item.value);</td></tr><tr class="miss"><td class="line">219</td><td class="hits">0</td><td class="source"> valid.some(function(validItem){</td></tr><tr class="miss"><td class="line">220</td><td class="hits">0</td><td class="source"> var flag;</td></tr><tr class="miss"><td class="line">221</td><td class="hits">0</td><td class="source"> if (typeof validItem === 'function') {</td></tr><tr class="miss"><td class="line">222</td><td class="hits">0</td><td class="source"> flag = validItem(item.value, item);</td></tr><tr class="miss"><td class="line">223</td><td class="hits">0</td><td class="source"> if (typeof flag === 'string') {</td></tr><tr class="miss"><td class="line">224</td><td class="hits">0</td><td class="source"> result[item.name] = flag;</td></tr><tr class="miss"><td class="line">225</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">226</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">227</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">228</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">229</td><td class="hits">0</td><td class="source"> flag = instance[validItem].apply(instance, item[validItem + '_args'] || []);</td></tr><tr class="miss"><td class="line">230</td><td class="hits">0</td><td class="source"> if (!flag) {</td></tr><tr class="miss"><td class="line">231</td><td class="hits">0</td><td class="source"> result[item.name] = item.msg[validItem];</td></tr><tr class="miss"><td class="line">232</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">233</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">234</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">235</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">236</td><td class="hits">0</td><td class="source"> return result;</td></tr><tr><td class="line">237</td><td class="hits"></td><td class="source">};</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/WebSocket.js">/Users/welefen/Develop/git/thinkjs/lib/Lib/Util/WebSocket.js</h2><div id="stats" class="terrible"><div class="percentage">8%</div><div class="sloc">107</div><div class="hits">9</div><div class="misses">98</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"><td class="line">1</td><td class="hits">1</td><td class="source">var thinkHttp = thinkRequire('Http');</td></tr><tr class="hit"><td class="line">2</td><td class="hits">1</td><td class="source">var url = require('url');</td></tr><tr class="hit"><td class="line">3</td><td class="hits">1</td><td class="source">var websocket = require('websocket').server;</td></tr><tr class="hit"><td class="line">4</td><td class="hits">1</td><td class="source">var querystring = require('querystring');</td></tr><tr><td class="line">5</td><td class="hits"></td><td class="source"> </td></tr><tr class="hit"><td class="line">6</td><td class="hits">1</td><td class="source">var WebSocket = module.exports = Class(function(){</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source"> 'use strict';</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">9</td><td class="hits"></td><td class="source"> * socket初始化id</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source"> * @type {Number}</td></tr><tr><td class="line">11</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">12</td><td class="hits">1</td><td class="source"> var socketId = 1000;</td></tr><tr class="hit"><td class="line">13</td><td class="hits">1</td><td class="source"> return {</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source"> init: function(httpServer, app){</td></tr><tr class="miss"><td class="line">15</td><td class="hits">0</td><td class="source"> this.httpServer = httpServer;</td></tr><tr class="miss"><td class="line">16</td><td class="hits">0</td><td class="source"> this.app = app;</td></tr><tr><td class="line">17</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">18</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source"> * 检测origin是否合法</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source"> * @param {[type]} origin [description]</td></tr><tr><td class="line">21</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">23</td><td class="hits"></td><td class="source"> originIsAllowed: function(origin){</td></tr><tr class="miss"><td class="line">24</td><td class="hits">0</td><td class="source"> var allowOrigins = C('websocket_allow_origin');</td></tr><tr class="miss"><td class="line">25</td><td class="hits">0</td><td class="source"> if (!allowOrigins) {</td></tr><tr class="miss"><td class="line">26</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr><td class="line">27</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">28</td><td class="hits">0</td><td class="source"> var info = url.parse(origin);</td></tr><tr class="miss"><td class="line">29</td><td class="hits">0</td><td class="source"> var hostname = info.hostname;</td></tr><tr class="miss"><td class="line">30</td><td class="hits">0</td><td class="source"> if (isString(allowOrigins) &amp;&amp; allowOrigins === hostname) {</td></tr><tr class="miss"><td class="line">31</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr class="miss"><td class="line">32</td><td class="hits">0</td><td class="source"> }else if (isArray(allowOrigins) &amp;&amp; allowOrigins.indexOf(hostname) &gt; -1) {</td></tr><tr class="miss"><td class="line">33</td><td class="hits">0</td><td class="source"> return true;</td></tr><tr class="miss"><td class="line">34</td><td class="hits">0</td><td class="source"> }else if (isFunction(allowOrigins)) {</td></tr><tr class="miss"><td class="line">35</td><td class="hits">0</td><td class="source"> return allowOrigins(hostname, info);</td></tr><tr><td class="line">36</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">37</td><td class="hits">0</td><td class="source"> return false;</td></tr><tr><td class="line">38</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">39</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">40</td><td class="hits"></td><td class="source"> * 选择子协议</td></tr><tr><td class="line">41</td><td class="hits"></td><td class="source"> * @param {[type]} protocolFullCaseMap [description]</td></tr><tr><td class="line">42</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">43</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">44</td><td class="hits"></td><td class="source"> getSubProtocal: function(protocolFullCaseMap){</td></tr><tr class="miss"><td class="line">45</td><td class="hits">0</td><td class="source"> var selectedProtocal = C('websocket_sub_protocal');</td></tr><tr class="miss"><td class="line">46</td><td class="hits">0</td><td class="source"> if (isFunction(selectedProtocal)) {</td></tr><tr class="miss"><td class="line">47</td><td class="hits">0</td><td class="source"> var subProtocals = Object.values(protocolFullCaseMap);</td></tr><tr class="miss"><td class="line">48</td><td class="hits">0</td><td class="source"> selectedProtocal = selectedProtocal(subProtocals);</td></tr><tr><td class="line">49</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">50</td><td class="hits">0</td><td class="source"> return selectedProtocal;</td></tr><tr><td class="line">51</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">52</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">53</td><td class="hits"></td><td class="source"> * 建立连接处理</td></tr><tr><td class="line">54</td><td class="hits"></td><td class="source"> * @param {[type]} request [description]</td></tr><tr><td class="line">55</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">56</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">57</td><td class="hits"></td><td class="source"> openHandle: function(request, protocal){</td></tr><tr class="miss"><td class="line">58</td><td class="hits">0</td><td class="source"> var req = request.httpRequest;</td></tr><tr class="miss"><td class="line">59</td><td class="hits">0</td><td class="source"> if (req.url === '/') {</td></tr><tr class="miss"><td class="line">60</td><td class="hits">0</td><td class="source"> return getPromise([]);</td></tr><tr><td class="line">61</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">62</td><td class="hits">0</td><td class="source"> var deferred = getDefer();</td></tr><tr class="miss"><td class="line">63</td><td class="hits">0</td><td class="source"> var fn = function(){};</td></tr><tr class="miss"><td class="line">64</td><td class="hits">0</td><td class="source"> var res = {setHeader: fn, end: fn, write: fn};</td></tr><tr class="miss"><td class="line">65</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">66</td><td class="hits">0</td><td class="source"> thinkHttp(req, res).run(function(http){</td></tr><tr class="miss"><td class="line">67</td><td class="hits">0</td><td class="source"> http.websocket = request.socket;</td></tr><tr><td class="line">68</td><td class="hits"></td><td class="source"> //子协议</td></tr><tr class="miss"><td class="line">69</td><td class="hits">0</td><td class="source"> http.websocket_sub_protocal = protocal;</td></tr><tr class="miss"><td class="line">70</td><td class="hits">0</td><td class="source"> self.app.listener(http).then(function(){</td></tr><tr class="miss"><td class="line">71</td><td class="hits">0</td><td class="source"> deferred.resolve({</td></tr><tr><td class="line">72</td><td class="hits"></td><td class="source"> cookie: Object.values(http._cookie),</td></tr><tr><td class="line">73</td><td class="hits"></td><td class="source"> http: http</td></tr><tr><td class="line">74</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">75</td><td class="hits"></td><td class="source"> }).catch(function(err){</td></tr><tr class="miss"><td class="line">76</td><td class="hits">0</td><td class="source"> deferred.reject(err);</td></tr><tr><td class="line">77</td><td class="hits"></td><td class="source"> })</td></tr><tr><td class="line">78</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">79</td><td class="hits">0</td><td class="source"> return deferred.promise;</td></tr><tr><td class="line">80</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">81</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">82</td><td class="hits"></td><td class="source"> * 消息处理</td></tr><tr><td class="line">83</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">84</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">85</td><td class="hits"></td><td class="source"> messageHandle: function(message, connection, app, type){</td></tr><tr class="miss"><td class="line">86</td><td class="hits">0</td><td class="source"> if (type !== 'utf8') {</td></tr><tr class="miss"><td class="line">87</td><td class="hits">0</td><td class="source"> connection.socket.send(WebSocket.ERROR_MESSAGE.TYPE_ERROR, message + ' is not valid json');</td></tr><tr class="miss"><td class="line">88</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">89</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">90</td><td class="hits"></td><td class="source"> //解析数据</td></tr><tr class="miss"><td class="line">91</td><td class="hits">0</td><td class="source"> try{</td></tr><tr class="miss"><td class="line">92</td><td class="hits">0</td><td class="source"> message = JSON.parse(message);</td></tr><tr><td class="line">93</td><td class="hits"></td><td class="source"> }catch(e){</td></tr><tr class="miss"><td class="line">94</td><td class="hits">0</td><td class="source"> connection.socket.send(WebSocket.ERROR_MESSAGE.INVALID_JSON, message + ' is not valid json');</td></tr><tr class="miss"><td class="line">95</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">96</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">97</td><td class="hits">0</td><td class="source"> if (message.jsonrpc !== '2.0') {</td></tr><tr class="miss"><td class="line">98</td><td class="hits">0</td><td class="source"> connection.socket.send(WebSocket.ERROR_MESSAGE.INVALID_JSONRPC, 'data.jsonrpc must be 2.0');</td></tr><tr class="miss"><td class="line">99</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">100</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">101</td><td class="hits">0</td><td class="source"> var method = message.method + '';</td></tr><tr class="miss"><td class="line">102</td><td class="hits">0</td><td class="source"> if (!method) {</td></tr><tr class="miss"><td class="line">103</td><td class="hits">0</td><td class="source"> connection.socket.send(WebSocket.ERROR_MESSAGE.INVALID_METHOD, 'data.method is not valid');</td></tr><tr class="miss"><td class="line">104</td><td class="hits">0</td><td class="source"> return;</td></tr><tr><td class="line">105</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">106</td><td class="hits">0</td><td class="source"> var pars = message.params;</td></tr><tr class="miss"><td class="line">107</td><td class="hits">0</td><td class="source"> var headers = {};</td></tr><tr class="miss"><td class="line">108</td><td class="hits">0</td><td class="source"> if (isObject(message.params.headers)) {</td></tr><tr class="miss"><td class="line">109</td><td class="hits">0</td><td class="source"> headers = message.params.headers;</td></tr><tr class="miss"><td class="line">110</td><td class="hits">0</td><td class="source"> pars = message.params.data;</td></tr><tr><td class="line">111</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">112</td><td class="hits">0</td><td class="source"> if (isObject(pars)) {</td></tr><tr class="miss"><td class="line">113</td><td class="hits">0</td><td class="source"> method += (method.indexOf('?') &gt; -1 ? '&amp;' : '?') + querystring.stringify(pars)</td></tr><tr><td class="line">114</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">115</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">116</td><td class="hits">0</td><td class="source"> var data = {</td></tr><tr><td class="line">117</td><td class="hits"></td><td class="source"> host: '',</td></tr><tr><td class="line">118</td><td class="hits"></td><td class="source"> url: method,</td></tr><tr><td class="line">119</td><td class="hits"></td><td class="source"> headers: headers,</td></tr><tr><td class="line">120</td><td class="hits"></td><td class="source"> write: function(data, encoding, errMsg){</td></tr><tr class="miss"><td class="line">121</td><td class="hits">0</td><td class="source"> var pars = self.getRPCData(JSON.parse(data), errMsg);</td></tr><tr class="miss"><td class="line">122</td><td class="hits">0</td><td class="source"> pars.id = message.id;</td></tr><tr class="miss"><td class="line">123</td><td class="hits">0</td><td class="source"> connection.send(JSON.stringify(pars));</td></tr><tr><td class="line">124</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">125</td><td class="hits"></td><td class="source"> end: function(data){</td></tr><tr class="miss"><td class="line">126</td><td class="hits">0</td><td class="source"> if (data) {</td></tr><tr class="miss"><td class="line">127</td><td class="hits">0</td><td class="source"> this.write(data);</td></tr><tr><td class="line">128</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">129</td><td class="hits">0</td><td class="source"> connection.close();</td></tr><tr><td class="line">130</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">131</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">132</td><td class="hits">0</td><td class="source"> var defaultHttp = thinkHttp.getDefaultHttp(data);</td></tr><tr class="miss"><td class="line">133</td><td class="hits">0</td><td class="source"> var httpInstance = thinkHttp(defaultHttp.req, defaultHttp.res);</td></tr><tr><td class="line">134</td><td class="hits"></td><td class="source"> //将websocket实例添加到http对象上</td></tr><tr class="miss"><td class="line">135</td><td class="hits">0</td><td class="source"> httpInstance.http.websocket = connection.socket;</td></tr><tr class="miss"><td class="line">136</td><td class="hits">0</td><td class="source"> httpInstance.run(app.listener);</td></tr><tr><td class="line">137</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">138</td><td class="hits"></td><td class="source"> /**</td></tr><tr><td class="line">139</td><td class="hits"></td><td class="source"> * 获取rpc数据对象</td></tr><tr><td class="line">140</td><td class="hits"></td><td class="source"> * @param {[type]} data [description]</td></tr><tr><td class="line">141</td><td class="hits"></td><td class="source"> * @param {[type]} errMsg [description]</td></tr><tr><td class="line">142</td><td class="hits"></td><td class="source"> * @return {[type]} [description]</td></tr><tr><td class="line">143</td><td class="hits"></td><td class="source"> */</td></tr><tr><td class="line">144</td><td class="hits"></td><td class="source"> getRPCData: function(data, errMsg){</td></tr><tr class="miss"><td class="line">145</td><td class="hits">0</td><td class="source"> var pars = {jsonrpc: '2.0'};</td></tr><tr class="miss"><td class="line">146</td><td class="hits">0</td><td class="source"> if (errMsg) {</td></tr><tr class="miss"><td class="line">147</td><td class="hits">0</td><td class="source"> pars.error = {code: data, message: errMsg};</td></tr><tr><td class="line">148</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">149</td><td class="hits">0</td><td class="source"> pars.result = data;</td></tr><tr><td class="line">150</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">151</td><td class="hits">0</td><td class="source"> return pars;</td></tr><tr><td class="line">152</td><td class="hits"></td><td class="source"> },</td></tr><tr><td class="line">153</td><td class="hits"></td><td class="source"> run: function(){</td></tr><tr class="miss"><td class="line">154</td><td class="hits">0</td><td class="source"> var instance = new websocket({</td></tr><tr><td class="line">155</td><td class="hits"></td><td class="source"> httpServer: this.httpServer,</td></tr><tr><td class="line">156</td><td class="hits"></td><td class="source"> autoAcceptConnections: false</td></tr><tr><td class="line">157</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">158</td><td class="hits">0</td><td class="source"> var self = this;</td></tr><tr class="miss"><td class="line">159</td><td class="hits">0</td><td class="source"> instance.on('request', function(request){</td></tr><tr><td class="line">160</td><td class="hits"></td><td class="source"> //检测origin</td></tr><tr class="miss"><td class="line">161</td><td class="hits">0</td><td class="source"> if (!self.originIsAllowed(request.origin)) {</td></tr><tr class="miss"><td class="line">162</td><td class="hits">0</td><td class="source"> return request.reject();</td></tr><tr><td class="line">163</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">164</td><td class="hits">0</td><td class="source"> var socket = request.socket;</td></tr><tr class="miss"><td class="line">165</td><td class="hits">0</td><td class="source"> socket.id = socketId++;</td></tr><tr class="miss"><td class="line">166</td><td class="hits">0</td><td class="source"> socket.activeTime = Date.now();</td></tr><tr><td class="line">167</td><td class="hits"></td><td class="source"> //选择子协议</td></tr><tr class="miss"><td class="line">168</td><td class="hits">0</td><td class="source"> var protocal = self.getSubProtocal(request.protocolFullCaseMap);</td></tr><tr class="miss"><td class="line">169</td><td class="hits">0</td><td class="source"> return self.openHandle(request, protocal).then(function(data){</td></tr><tr class="miss"><td class="line">170</td><td class="hits">0</td><td class="source"> var connection = socket.connection = request.accept(protocal, request.origin, data.cookie);</td></tr><tr class="miss"><td class="line">171</td><td class="hits">0</td><td class="source"> socket.close = function(){</td></tr><tr class="miss"><td class="line">172</td><td class="hits">0</td><td class="source"> connection.close();</td></tr><tr><td class="line">173</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">174</td><td class="hits">0</td><td class="source"> if (!socket.send) {</td></tr><tr class="miss"><td class="line">175</td><td class="hits">0</td><td class="source"> socket.send = function(data, errMsg){</td></tr><tr class="miss"><td class="line">176</td><td class="hits">0</td><td class="source"> var pars = self.getRPCData(data, errMsg);</td></tr><tr class="miss"><td class="line">177</td><td class="hits">0</td><td class="source"> connection.send(JSON.stringify(pars));</td></tr><tr><td class="line">178</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">179</td><td class="hits"></td><td class="source"> }</td></tr><tr class="miss"><td class="line">180</td><td class="hits">0</td><td class="source"> var messageHandle = C('websocket_message_handle');</td></tr><tr class="miss"><td class="line">181</td><td class="hits">0</td><td class="source"> connection.on('message', function(message) {</td></tr><tr class="miss"><td class="line">182</td><td class="hits">0</td><td class="source"> socket.activeTime = Date.now();</td></tr><tr class="miss"><td class="line">183</td><td class="hits">0</td><td class="source"> var data = message.type === 'utf8' ? message.utf8Data : message.binaryData;</td></tr><tr class="miss"><td class="line">184</td><td class="hits">0</td><td class="source"> if (isFunction(messageHandle)) {</td></tr><tr class="miss"><td class="line">185</td><td class="hits">0</td><td class="source"> messageHandle(data, connection, self.app, message.type);</td></tr><tr><td class="line">186</td><td class="hits"></td><td class="source"> }else{</td></tr><tr class="miss"><td class="line">187</td><td class="hits">0</td><td class="source"> self.messageHandle(data, connection, self.app, message.type);</td></tr><tr><td class="line">188</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">189</td><td class="hits"></td><td class="source"> });</td></tr><tr class="miss"><td class="line">190</td><td class="hits">0</td><td class="source"> connection.on('close', function() {</td></tr><tr class="miss"><td class="line">191</td><td class="hits">0</td><td class="source"> data.http.emit('websocket.close');</td></tr><tr><td class="line">192</td><td class="hits"></td><td class="source"> });</td></tr><tr><td class="line">193</td><td class="hits"></td><td class="source"> }).catch(function(err){</td></tr><tr class="miss"><td class="line">194</td><td class="hits">0</td><td class="source"> request.reject(err);</td></tr><tr><td class="line">195</td><td class="hits"></td><td class="source"> })</td></tr><tr><td class="line">196</td><td class="hits"></td><td class="source"> })</td></tr><tr><td class="line">197</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">198</td><td class="hits"></td><td class="source"> }</td></tr><tr><td class="line">199</td><td class="hits"></td><td class="source">});</td></tr><tr><td class="line">200</td><td class="hits"></td><td class="source">/**</td></tr><tr><td class="line">201</td><td class="hits"></td><td class="source"> * 错误信息</td></tr><tr><td class="line">202</td><td class="hits"></td><td class="source"> * @type {Object}</td></tr><tr><td class="line">203</td><td class="hits"></td><td class="source"> */</td></tr><tr class="hit"><td class="line">204</td><td class="hits">1</td><td class="source">WebSocket.ERROR_MESSAGE = {</td></tr><tr><td class="line">205</td><td class="hits"></td><td class="source"> TYPE_ERROR: -100001, //数据类型错误</td></tr><tr><td class="line">206</td><td class="hits"></td><td class="source"> INVALID_JSON: -100002, //不是合法的json</td></tr><tr><td class="line">207</td><td class="hits"></td><td class="source"> INVALID_JSONRPC: -100003, //不是jsonrpc数据格式</td></tr><tr><td class="line">208</td><td class="hits"></td><td class="source"> INVALID_METHOD: -100004 //请求方法不合法</td></tr><tr><td class="line">209</td><td class="hits"></td><td class="source">}</td></tr></tbody></table></div><div class="file"><h2 id="/Users/welefen/Develop/git/thinkjs/lib/think.js">/Users/welefen/Develop/git/thinkjs/lib/think.js</h2><div id="stats" class="high"><div class="percentage">100%</div><div class="sloc">12</div><div class="hits">12</div><div class="misses">0</div></div><table id="source"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr class="hit"><td class="line">1</td><td class="hits">1</td><td class="source">var path = require('path');</td></tr><tr class="hit"><td class="line">2</td><td class="hits">1</td><td class="source">var fs = require('fs');</td></tr><tr><td class="line">3</td><td class="hits"></td><td class="source"> </td></tr><tr><td class="line">4</td><td class="hits"></td><td class="source">//APP根目錄</td></tr><tr class="hit"><td class="line">5</td><td class="hits">1</td><td class="source">global.APP_PATH = global.APP_PATH ? path.normalize(global.APP_PATH) : path.dirname(__dirname) + '/App';</td></tr><tr><td class="line">6</td><td class="hits"></td><td class="source">//RUNTIME目录</td></tr><tr class="hit"><td class="line">7</td><td class="hits">1</td><td class="source">global.RUNTIME_PATH = global.RUNTIME_PATH ? path.normalize(global.RUNTIME_PATH) : global.APP_PATH + '/Runtime';</td></tr><tr><td class="line">8</td><td class="hits"></td><td class="source">//DEBUG模式</td></tr><tr class="hit"><td class="line">9</td><td class="hits">1</td><td class="source">global.APP_DEBUG = global.APP_DEBUG || false;</td></tr><tr><td class="line">10</td><td class="hits"></td><td class="source">//静态资源文件的根目录</td></tr><tr class="hit"><td class="line">11</td><td class="hits">1</td><td class="source">global.RESOURCE_PATH = global.RESOURCE_PATH || '';</td></tr><tr><td class="line">12</td><td class="hits"></td><td class="source">//THINKJS的根目录</td></tr><tr class="hit"><td class="line">13</td><td class="hits">1</td><td class="source">global.THINK_PATH = __dirname;</td></tr><tr><td class="line">14</td><td class="hits"></td><td class="source">//默认为http模式</td></tr><tr class="hit"><td class="line">15</td><td class="hits">1</td><td class="source">global.APP_MODE = 'http';</td></tr><tr><td class="line">16</td><td class="hits"></td><td class="source">//命令行模式</td></tr><tr class="hit"><td class="line">17</td><td class="hits">1</td><td class="source">if (process.argv[2]) {</td></tr><tr class="hit"><td class="line">18</td><td class="hits">1</td><td class="source"> APP_MODE = 'cli';</td></tr><tr><td class="line">19</td><td class="hits"></td><td class="source">}</td></tr><tr><td class="line">20</td><td class="hits"></td><td class="source">//从package.json文件里获取版本号</td></tr><tr class="hit"><td class="line">21</td><td class="hits">1</td><td class="source">global.THINK_VERSION = JSON.parse(fs.readFileSync(global.THINK_PATH + '/../package.json', 'utf8')).version;</td></tr><tr><td class="line">22</td><td class="hits"></td><td class="source">//启动</td></tr><tr class="hit"><td class="line">23</td><td class="hits">1</td><td class="source">require(global.THINK_PATH + '/Lib/Core/Think.js').start();</td></tr></tbody></table></div></div></div></body></html>