Monday, October 2, 2017

how to get sequence int value by name in mysql

DELIMITER $$

CREATE FUNCTION `seqval` (`seq_name` VARCHAR(100))
RETURNS BIGINT(20) NOT DETERMINISTIC
BEGIN
    DECLARE cur_val bigint(20);

SELECT intval INTO cur_val FROM seqcontract
WHERE name = seq_name;

IF cur_val IS NULL THEN
SET cur_val = 1;

INSERT seqcontract(name, intval)
VALUES(seq_name, cur_val);
ELSE
SET cur_val = cur_val + 1;

UPDATE seqcontract
SET intval = cur_val
WHERE name = seq_name;
END IF;

RETURN cur_val;
END$$

Thursday, August 3, 2017

DOM and javascript photo slider simple

css

.slideshow-container {
        position: relative;
        width: 100%;
        height: 500px;
        overflow: hidden;
        .slides {
            display: block;
            //position: absolute;
            margin: 0 auto;
            width: 1600px;
            height: 500px;
            visibility: hidden;
            opacity: 0;
            img {
                display: block;
                width: 1600px;
                height: 500px;
            }
            /* Fading animation */
            &.fadein {
                visibility: visible;
                opacity: 1;
                @include animation(slider-links-fadein 1s ease-out);
            }
        }
        /* Next & previous buttons */
        .prev, .next {
            cursor: pointer;
            position: absolute;
            top: 50%;
            width: auto;
            margin-top: -22px;
            padding: 16px;
            color: white;
            font-weight: bold;
            font-size: 18px;
            transition: 0.6s ease;
            border-radius: 0 3px 3px 0;
        }

        /* Position the "next button" to the right */
        .next {
            right: 0;
            border-radius: 3px 0 0 3px;
        }

        /* On hover, add a black background color with a little bit see-through */
        .prev:hover, .next:hover {
            background-color: rgba(0,0,0,0.8);
        }
    }

    /* Caption text */
    .text {
        padding: 15px;
        position: absolute;
        left: 0;
        top: 0;
        background-color: rgba(0,0,0,0.5);
        color: #f2f2f2;
        font-size: 19px;
        width: 400px;
        height: 100%;
        margin-left: 60%;
    }

    /* The dots/bullets/indicators */
    .dot {
        cursor: pointer;
        height: 13px;
        width: 13px;
        margin: 0 2px;
        background-color: #bbb;
        border-radius: 50%;
        display: inline-block;
        transition: background-color 0.6s ease;
        &.active, &:hover {
            background-color: #717171;
        }
    }



script


<script>
        var slideIndex = 0;
        function plusSlides(n) {
            showSlides(slideIndex += n);
        }
        function currentSlide(n) {
            showSlides(slideIndex = n);
        }
        function showSlides(n) {
            var i;
            var slides = document.getElementsByClassName("slides");
            var dots = document.getElementsByClassName("dot");
            if (n > slides.length) {
                slideIndex = 1;
            }
            if (n < 1) {
                slideIndex = slides.length;
            }
            for (i = 0; i < slides.length; i++) {
                slides[i].className = "anim9s slides";
            }
            for (i = 0; i < dots.length; i++) {
                dots[i].className = dots[i].className.replace(" active", "");
            }
            slides[slideIndex - 1].className = "anim9s slides fadein";
            dots[slideIndex - 1].className += " active";
        }
        var autoSlides = function () {
            var i;
            var slides = document.getElementsByClassName("slides");
            for (i = 0; i < slides.length; i++) {
                slides[i].className = "anim9s slides";
            }
            slideIndex++;
            if (slideIndex > slides.length) {
                slideIndex = 1;
            }
            slides[slideIndex - 1].className = "anim9s slides fadein";
            setTimeout(autoSlides, 5000); // Change image every 2 seconds
        };
        autoSlides();
    </script>

Tuesday, June 20, 2017

how to fix Got error 'this version of PCRE is compiled without UTF support at offset 0' from regexp

on mysql error:
how to fix Got error 'this version of PCRE is compiled without UTF support at offset 0' from regexp

fix:
1.
install aclocal-1.15 from
https://github.com/gp187/nginx-builder/blob/master/fix/aclocal.sh
2.
./configure --prefix=/opt/lampp --enable-utf8 --enable-unicode-properties && make
make install

install automake 1.15 using aclocal.sh

#!/bin/bash

# run as root only
if [[ $EUID -ne 0 ]] ; then
    echo -e "\e[1;39m[   \e[31mError\e[39m   ] need root access to run this script\e[0;39m"
    exit 1
fi

function install_automake() {
    [ $# -eq 0 ] && { run_error "Usage: install_automake <version>"; exit; }
    local VERSION=${1}
    wget ftp://ftp.gnu.org/gnu/automake/automake-${VERSION}.tar.gz &> /dev/null
    if [ -f "automake-${VERSION}.tar.gz" ]; then
            tar -xzf automake-${VERSION}.tar.gz
            cd automake-${VERSION}/
            ./configure
            make && make install
            echo -e "\e[1;39m[   \e[1;32mOK\e[39m   ] automake-${VERSION} installed\e[0;39m"

        else
            echo -e "\e[1;39m[   \e[31mError\e[39m   ] cannot fetch file from ftp://ftp.gnu.org/gnu/automake/ \e[0;39m"
            exit 1
    fi
}
install_automake 1.15

Monday, June 19, 2017

create database , user , grant privileges and import in mysql

CREATE DATABASE mydb
  DEFAULT CHARACTER SET utf8
  DEFAULT COLLATE utf8_general_ci;

CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON DbName.* TO 'newuser'@'localhost' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON DbName.* TO 'newuser'@'localhost' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;
SHOW GRANT FOR 'newuser'@'localhost';
or
DROP USER ‘demo’@‘localhost’;

>mysql -u root -p database_name < database.sql

Tuesday, April 4, 2017

angular example for todo list using form ng-submit

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app="myApp" ng-controller="todoCtrl">

<h2>My Todo List</h2>

<form ng-submit="todoAdd()">
    <input type="text" ng-model="todoInput" size="50" placeholder="Add New">
    <input type="submit" value="Add New">
</form>

<br>

<div ng-repeat="x in todoList">
    <input type="checkbox" ng-model="x.done"> <span ng-bind="x.todoText"></span>
</div>

<p><button ng-click="remove()">Remove marked</button></p>

<script>
var app = angular.module('myApp', []);
app.controller('todoCtrl', function($scope) {
    $scope.todoList = [{todoText:'Clean House', done:false}];

    $scope.todoAdd = function() {
        $scope.todoList.push({todoText:$scope.todoInput, done:false});
        $scope.todoInput = "";
    };

    $scope.remove = function() {
        var oldList = $scope.todoList;
        $scope.todoList = [];
        angular.forEach(oldList, function(x) {
            if (!x.done) $scope.todoList.push(x);
        });
    };
});
</script>

</body>
</html>

Thursday, March 23, 2017

oracle inserted row OUT SYS_REFCURSOR by execution procedure

CREATE TABLE "BOROO"."CMS_TEMP"
   (    "ID" VARCHAR2(36 BYTE) DEFAULT SYS_GUID() NOT NULL ENABLE,
    "NAME" NVARCHAR2(150),
    "RCDATE" TIMESTAMP (6) DEFAULT SYS_EXTRACT_UTC(SYSTIMESTAMP) NOT NULL ENABLE
   )
 
procedure

create or replace PROCEDURE INSEL_TEMP (p_name NVARCHAR2, v_cur OUT SYS_REFCURSOR)
AS
v_id NVARCHAR2(36);
BEGIN
INSERT INTO CMS_TEMP (NAME) VALUES (p_name) RETURNING ID INTO v_id;
COMMIT;
OPEN v_cur FOR SELECT ID,NAME,RCDATE FROM CMS_TEMP WHERE ID=v_id;
END;



call






DECLARE
  l_cursor  SYS_REFCURSOR;
  l_id   cms_temp.ID%TYPE;
  l_name   cms_temp.NAME%TYPE;
  l_rcdate  cms_temp.RCDATE%TYPE;
BEGIN
  INSEL_TEMP('name 1', l_cursor);
 
  LOOP FETCH l_cursor
    INTO l_id, l_name, l_rcdate;
    EXIT WHEN l_cursor%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(l_id || ' | ' || l_name || ' | ' || l_rcdate);
  END LOOP;
  CLOSE l_cursor;
END;

Tuesday, March 21, 2017

oracle SYS_EXTRACT_UTC(SYSTIMESTAMP), mssql GETUTCDATE(), mysql CURRENT_TIMESTAMP

inORACLE

DROP TABLE "CMS_TEMP";

CREATE TABLE "CMS_TEMP" (  
"ID" VARCHAR2(36) DEFAULT SYS_GUID() NOT NULL,
"NAME" NVARCHAR2(150),
"RCDATE" TIMESTAMP DEFAULT SYS_EXTRACT_UTC(SYSTIMESTAMP) NOT NULL
);

insert into "BOROO"."CMS_TEMP" (NAME)
values ('new name 1');

select TO_CHAR(RCDATE, 'YYYY-MM-DD HH24:MI:SS.FF') from CMS_TEMP;


inMSSQL


DROP TABLE [dbo].[table1]
GO
/****** Object:  Table [dbo].[table1]    Script Date: 3/21/2017 5:50:45 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[table1](
    [ID] [uniqueidentifier] ROWGUIDCOL NOT NULL CONSTRAINT [DF_table1_ID]  DEFAULT (newid()),
    [Name] [nvarchar](50) NOT NULL,
    [rcdate] datetime NOT NULL DEFAULT GETUTCDATE()
) ON [PRIMARY]
GO
insert into table1(name)
values ('name 1');
GO
select rcdate from table1;


inMySQL

CREATE TABLE `table1` (
  `id` char(36) DEFAULT NULL,
  `name` varchar(250) NOT NULL,
  `rcdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE OR REPLACE PROCEDURE test for REF CURSOR

CREATE OR REPLACE PROCEDURE test
IS
  TYPE ref_cursor_type IS REF CURSOR;
  c_ref_cursor ref_cursor_type;
  v_sql VARCHAR2(1000) := 'SELECT 1 FROM some_object';
  v_dummy NUMBER;
BEGIN
  OPEN c_ref_cursor FOR v_sql;
  FETCH c_ref_cursor INTO v_dummy;
  CLOSE c_ref_cursor;
END;

oracle sys_guid(), mssql newid(), mysql trigger all for default uniqueidentifier ID

inORACLE


DROP TABLE "CMS_TEMP";

CREATE TABLE "CMS_TEMP" (   
"ID" VARCHAR2(36) NOT NULL,
"NAME" NVARCHAR2(150),
"RCTIME" TIMESTAMP (6) DEFAULT SYS_EXTRACT_UTC(SYSTIMESTAMP) NOT NULL
);

create or replace FUNCTION NEWID RETURN VARCHAR2 IS guid VARCHAR2(36);
BEGIN
    SELECT SYS_GUID() INTO guid FROM DUAL;
guid := regexp_replace(rawtohex(sys_guid())
       , '([A-F0-9]{8})([A-F0-9]{4})([A-F0-9]{4})([A-F0-9]{4})([A-F0-9]{12})'
       , '\1-\2-\3-\4-\5');
--OR
guid := SUBSTR(guid,  1, 8) ||
        '-' || SUBSTR(guid,  9, 4) ||
        '-' || SUBSTR(guid, 13, 4) ||
        '-' || SUBSTR(guid, 17, 4) ||
        '-' || SUBSTR(guid, 21);
    RETURN guid;
END NEWID;

create or replace TRIGGER SetGUIDforCMS_TEMP BEFORE INSERT ON CMS_TEMP
FOR EACH ROW
BEGIN
    :new.ID := NEWID();
END;

insert into "CMS_TEMP" (NAME)
values ('new name 1');

select * from cms_temp;

DECLARE
  v_Return VARCHAR2(36);
BEGIN
  v_Return := NEWID;
  DBMS_OUTPUT.PUT_LINE(v_Return);
END;

select NEWID from dual;

inMSSQL


Data Type: uniqueidentifier
Default Value or Binding: (newid())

CREATE TABLE [dbo].[table1](
    [ID] [uniqueidentifier] ROWGUIDCOL NOT NULL CONSTRAINT [DF_table1_ID]  DEFAULT (newid()),
    [Name] [nvarchar](50) NOT NULL,
    [rcdate] datetime NOT NULL DEFAULT GETUTCDATE()
) ON [PRIMARY]
GO

inMYSQL

CREATE TRIGGER `before_insert_table1` BEFORE INSERT ON `table1`
FOR EACH ROW BEGIN
    SET new.id = UPPER(uuid());
END

Monday, March 20, 2017

php session start with save_path

<?php
$dr = $_SERVER['DOCUMENT_ROOT'];
echo '$dr is '.$dr.'<br>';
$dn = dirname($dr);
echo '$dn is '.$dn.'<br>';
$sp = $dn . '/../sessions';
echo '$sp is '.$sp.'<br>';
$rp = realpath($sp);/*C:/sessions on windows*/
echo '$rp is '.$rp.'<br>';
ini_set('session.save_path', $rp);
echo 'ini_get is '.ini_get('session.save_path').'<br>';
session_start();
echo 'session is '.$_SESSION['hello'];
$_SESSION['hello'] = 'boroo';

Friday, March 17, 2017

oracle CREATE OR REPLACE Function with cursor, if clause

CREATE OR REPLACE Function IncomeLevel
   ( name_in IN varchar2 )
   RETURN varchar2
IS
   monthly_value number(6);
   ILevel varchar2(20);

   cursor c1 is
     SELECT monthly_income
     FROM employees
     WHERE name = name_in;

BEGIN

   open c1;
   fetch c1 into monthly_value;
   close c1;

   IF monthly_value <= 4000 THEN
      ILevel := 'Low Income';

   ELSIF monthly_value > 4000 and monthly_value <= 7000 THEN
      ILevel := 'Avg Income';

   ELSIF monthly_value > 7000 and monthly_value <= 15000 THEN
      ILevel := 'Moderate Income';

   ELSE
      ILevel := 'High Income';

   END IF;

   RETURN ILevel;

END;

node.js dateFormat library with test by jsfiddle

http://jsfiddle.net/phZr7/1/

/*
     * Date Format 1.2.3
     * (c) 2007-2009 Steven Levithan <stevenlevithan.com>
     * MIT license
     *
     * Includes enhancements by Scott Trenda <scott.trenda.net>
     * and Kris Kowal <cixar.com/~kris.kowal/>
     *
     * Accepts a date, a mask, or a date and a mask.
     * Returns a formatted version of the given date.
     * The date defaults to the current date/time.
     * The mask defaults to dateFormat.masks.default.
     */

    var dateFormat = function () {
        var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
            timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
            timezoneClip = /[^-+\dA-Z]/g,
            pad = function (val, len) {
                val = String(val);
                len = len || 2;
                while (val.length < len) val = "0" + val;
                return val;
            };
  
        // Regexes and supporting functions are cached through closure
        return function (date, mask, utc) {
            var dF = dateFormat;
  
            // You can't provide utc if you skip other args (use the "UTC:" mask prefix)
            if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
                mask = date;
                date = undefined;
            }
  
            // Passing date through Date applies Date.parse, if necessary
            date = date ? new Date(date) : new Date;
            if (isNaN(date)) throw SyntaxError("invalid date");
  
            mask = String(dF.masks[mask] || mask || dF.masks["default"]);
  
            // Allow setting the utc argument via the mask
            if (mask.slice(0, 4) == "UTC:") {
                mask = mask.slice(4);
                utc = true;
            }
  
            var    _ = utc ? "getUTC" : "get",
                d = date[_ + "Date"](),
                D = date[_ + "Day"](),
                m = date[_ + "Month"](),
                y = date[_ + "FullYear"](),
                H = date[_ + "Hours"](),
                M = date[_ + "Minutes"](),
                s = date[_ + "Seconds"](),
                L = date[_ + "Milliseconds"](),
                o = utc ? 0 : date.getTimezoneOffset(),
                flags = {
                    d:    d,
                    dd:   pad(d),
                    ddd:  dF.i18n.dayNames[D],
                    dddd: dF.i18n.dayNames[D + 7],
                    m:    m + 1,
                    mm:   pad(m + 1),
                    mmm:  dF.i18n.monthNames[m],
                    mmmm: dF.i18n.monthNames[m + 12],
                    yy:   String(y).slice(2),
                    yyyy: y,
                    h:    H % 12 || 12,
                    hh:   pad(H % 12 || 12),
                    H:    H,
                    HH:   pad(H),
                    M:    M,
                    MM:   pad(M),
                    s:    s,
                    ss:   pad(s),
                    l:    pad(L, 3),
                    L:    pad(L > 99 ? Math.round(L / 10) : L),
                    t:    H < 12 ? "a"  : "p",
                    tt:   H < 12 ? "am" : "pm",
                    T:    H < 12 ? "A"  : "P",
                    TT:   H < 12 ? "AM" : "PM",
                    Z:    utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
                    o:    (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
                    S:    ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
                };
  
            return mask.replace(token, function ($0) {
                return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
            });
        };
    }();
  
    // Some common format strings
    dateFormat.masks = {
        "default":      "ddd mmm dd yyyy HH:MM:ss",
        shortDate:      "m/d/yy",
        mediumDate:     "mmm d, yyyy",
        longDate:       "mmmm d, yyyy",
        fullDate:       "dddd, mmmm d, yyyy",
        shortTime:      "h:MM TT",
        mediumTime:     "h:MM:ss TT",
        longTime:       "h:MM:ss TT Z",
        isoDate:        "yyyy-mm-dd",
        isoTime:        "HH:MM:ss",
        isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
        isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
    };
  
    // Internationalization strings
    dateFormat.i18n = {
        dayNames: [
            "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
            "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
        ],
        monthNames: [
            "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
            "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
        ]
    };
  
    // For convenience...
    Date.prototype.format = function (mask, utc) {
        return dateFormat(this, mask, utc);
    };

today = new Date();
alert(dateFormat.isoUtcDateTime);
var dateString = today.format(dateFormat.isoUtcDateTime);
alert(dateString);

Tuesday, March 14, 2017

npm install oracledb using python27,node-gyp,bcrypt,build-tools,oracle-instantclient in windows

1.
install python 2.7
>npm config set python python2.7

2.
download and extract Oracle Instant Client to C:\oracle\instantclient
C:\oracle\instantclient; add to PATH of system variables

3. may be, not use that
>npm install --global --production windows-build-tools
>npm config set msvs_version 2013 --global
>npm install bcrypt
>npm install -g node-gyp
>node-gyp rebuild

4.
http://landinghub.visualstudio.com/visual-cpp-build-tools
or
visual studio 2015 install
>npm config set msvs_version 2015

5.
>set OCI_LIB_DIR=C:\oracle\instantclient\sdk\lib\msvc
>set OCI_INC_DIR=C:\oracle\instantclient\sdk\include
or
>set OCI_LIB_DIR=C:\oracle\BOR\product\11.2.0\dbhome_1\OCI\lib\msvc
>set OCI_INC_DIR=C:\oracle\BOR\product\11.2.0\dbhome_1\OCI\include

6.
>npm install oracledb --save

Friday, March 10, 2017

VSCode task, Gulp-sass concat many js to one minify js, sass to compressed css

'use strict';
const gulp = require('gulp');
const autoprefixer = require('gulp-autoprefixer');
const sourcemaps = require('gulp-sourcemaps');
const concat = require('gulp-concat');
const uglify = require('gulp-uglify');
const sass = require('gulp-sass');
const path = require('path');

var _adminSassInc = path.resolve(__dirname'private/themes/admin/scss');
var _adminSass = './private/themes/admin/scss/*.scss';
var _adminSassMain = './private/themes/admin/scss/*.scss';
var _adminCssDest = './public/themes/admin/css/';
var _adminJsPrivate = [
    './private/themes/admin/jss/*.js'
];
var _adminJsPublic = './public/themes/admin/js/';
var _admin_js_name = 'ajs.js';

var _siteSassInc = path.resolve(__dirname'private/themes/default/scss');
var _siteSass = './private/themes/default/scss/*.scss';
var _siteSassMain = './private/themes/default/scss/*.scss';
var _siteCssDest = './public/themes/default/css/';
var _siteJsPrivate = [
    './private/themes/default/jss/jishee.js',
    './private/themes/default/jss/scripts.js'
];
var _siteJsPublic = './public/themes/default/js/';
var _site_js_name = 'sjs.js';


var _outputStyle = 'compressed';
var config = {
    sass: {
        style: 'expanded',
        outputStyle: _outputStyle,
        errLogToConsole: true,
        sourceMap: true
    },
    autoprefixer: {
        browsers: ['last 2 versions'],
        cascade: false
    }
};

/**
 * for admin themes
 */
var admin_css_task = function () {
    config.sass.includePaths = _adminSassInc;
    gulp.src(_adminSassMain)
        .pipe(sass(config.sass))
        .pipe(gulp.dest(_adminCssDest));
};
gulp.task('admin-css'admin_css_task);
var admin_js_task = function () {
    gulp.src(_adminJsPrivate)
        .pipe(concat(_admin_js_name))
        .pipe(uglify())
        .pipe(gulp.dest(_adminJsPublic))
};
gulp.task('admin-js'admin_js_task);

/**
 * for site themes
 */
var site_css_task = function () {
    config.sass.includePaths = _siteSassInc;
    gulp.src(_siteSassMain)
        .pipe(sass(config.sass))
        .pipe(gulp.dest(_siteCssDest));
};
gulp.task('site-css'site_css_task);
var site_js_task = function () {
    gulp.src(_siteJsPrivate)
        .pipe(concat(_site_js_name))
        .pipe(uglify())
        .pipe(gulp.dest(_siteJsPublic))
};
gulp.task('site-js'site_js_task);

/**
 * .pipe(sourcemaps.init())
        .pipe(sass(config.sass))
        .pipe(sourcemaps.write({ includeContent: false }))
        .pipe(sourcemaps.init({ loadMaps: true }))
        .pipe(autoprefixer(config.autoprefixer))
        .pipe(sourcemaps.write('.'))
 */

gulp.task('watch'function () {
    var changeHandler = function (evt) {
        console.log(
            '[watcher] File ' + evt.path.replace(/.*(?=sass)/'') + ' was ' + evt.type + ', compiling...'
        );
    };
    
    gulp.watch(_adminSassfunction () {
        setTimeout(function () {
            admin_css_task();
        }, 500);
    }).on('change'changeHandler);
    gulp.watch(_adminJsPrivateadmin_js_task);

    gulp.watch(_siteSassfunction () {
        setTimeout(function () {
            site_css_task();
        }, 500);
    }).on('change'changeHandler);
    gulp.watch(_siteJsPrivatesite_js_task);
});

gulp.task('run', ['admin-css''site-css''admin-js''site-js''watch']);

Dynamically injects @import statements into the main app.less file

// gulpfile.js
var gulp = require('gulp'),
    less = require('gulp-less'),
    inject = require('gulp-inject');

gulp.task('less', function() {
    return gulp.src('src/styles/main.less')
    /**
     * Dynamically injects @import statements into the main app.less file, allowing
     * .less files to be placed around the app structure with the component
     * or page they apply to.
     */
        .pipe(inject(gulp.src(['../**/*.less'], {read: false, cwd: 'src/styles/'}), {
            starttag: '/* inject:imports */',
            endtag: '/* endinject */',
            transform: function (filepath) {
                return '@import ".' + filepath + '";';
            }
        }))
        .pipe(less())
        .pipe(gulp.dest('build/styles'));
});

How to Automate Tasks in Visual Studio Code

var gulp = require('gulp');
var uglify = require('gulp-uglify');
var sass = require('gulp-sass');

var jsSrc = './js/src/**/*.js';
var sassSrc = './css/sass/**/*.scss';

gulp.task( 'scripts', function() {
  return  gulp.src( jsSrc )
                .pipe( uglify() )
                .pipe( gulp.dest( './js' ) )
});

gulp.task( 'styles', function() {
  return  gulp.src( sassSrc )
                .pipe( sass( { outputStyle: 'compressed' } ) )
                .pipe( gulp.dest( './css' ) );
});

gulp.task( 'automate', function() {
  gulp.watch( [ sassSrc, jsSrc ], [ 'scripts', 'styles' ] );
});

gulp.task( 'default', ['scripts', 'styles', 'automate'] );

Tuesday, March 7, 2017

oracle database date, timestamp, utc (SYS_EXTRACT_UTC(SYSTIMESTAMP)) field convert to local time example


  CREATE TABLE "BOROO"."CMS_TEMP"
   (    "ID" VARCHAR2(32 BYTE) DEFAULT SYS_GUID() NOT NULL ENABLE,
    "NAME" NVARCHAR2(150) NOT NULL ENABLE,
    "DESCR" NVARCHAR2(500),
    "ISDELETED" NUMBER(1,0) DEFAULT 0 NOT NULL ENABLE,
    "RCDATE" DATE NOT NULL ENABLE,
    "RCTIME" TIMESTAMP (6) DEFAULT SYS_EXTRACT_UTC(SYSTIMESTAMP) NOT NULL ENABLE
   ) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" ;


  CREATE UNIQUE INDEX "BOROO"."CMS_TEMP_INDEX1" ON "BOROO"."CMS_TEMP" ("ID")
  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" ;


  CREATE INDEX "BOROO"."CMS_TEMP_INDEX2" ON "BOROO"."CMS_TEMP" ("NAME")
  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" ;


  CREATE INDEX "BOROO"."CMS_TEMP_INDEX3" ON "BOROO"."CMS_TEMP" ("RCDATE" DESC)
  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" ;


INSERT INTO CMS_TEMP (NAME,DESCR,ISDELETED,RCDATE)
VALUES ('my name', 'миний тайлбар', 0, TO_DATE('2017-03-07 15:17:19', 'YYYY-MM-DD HH24:MI:SS'));

/*UTC timestamp field view as local date*/
SELECT ID,NAME,TO_CHAR(RCDATE, 'YYYY-MM-DD HH24:MI:SS') as DATETIME,RCTIME as UTC
,TO_CHAR(FROM_TZ(RCTIME, 'UTC') at LOCAL, 'YYYY-MM-DD HH24:MI:SSxFF6') as local
FROM CMS_TEMP;

/*UTC without TZH:TZM*/
SELECT SYSTIMESTAMP as local, SYS_EXTRACT_UTC(SYSTIMESTAMP) as utc, TO_CHAR(SYS_EXTRACT_UTC(SYSTIMESTAMP), 'YYYY-MM-DD HH24:MI:SSxFF6') as str from dual;

Wednesday, February 22, 2017

5 steps to making a Node.js frontend app 10x faster

Step 1: Parallelize Everything

In order to render the HTML page for any dashboard, the node.js application needs to retrieve a lot of data for the dashboard in question.
At minimum this means it needs to retrieve the data from the user’s current browsing session to check they’re logged in and it needs to pull in data about the user (e.g. the user’s name, which sites they have access to, their API key and the parameters of their GoSquared subscription), and about the site in question for the dashboard (site name, unique token etc).
In order to retrieve this data, the application needed to make several calls to internal API functions, many of which could take up to 2 seconds to complete. Each request was made by a separate Express middleware, which meant they were running in series. Each request would wait for the previous one to complete before starting.
Since node.js is perfectly suited to running multiple asynchronous functions in parallel, and since a lot of these internal API requests didn’t depend on each other, it made sense to parallelize them — fire off all the requests at once and then continue once they’ve all completed. We achieved this with the aid of the (incredibly useful) async module:
So instead of:
app.use(getUser);
app.use(getSiteList);
app.use(getCurrentSite);
app.use(getSubscription);
… we could do something like this:
function parallel(middlewares) {
  return function (req, res, next) {
    async.each(middlewares, function (mw, cb) {
      mw(req, res, cb);
    }, next);
  };
}

app.use(parallel([
  getUser,
  getSiteList,
  getCurrentSite,
  getSubscription
]));
Straight away this cut our average response time down from 10 seconds to roughly 1.5 seconds. But we knew we could still do better.

Step 2: Cache, Cache, Cache

Even once we’d parallelized all of our internal data-fetching, loading a dashboard was still pretty slow. The reason for this was because not only was the application fetching all this data for the initial page load, it was also fetching it for a lot of subsequent JavaScript requests (at this point we were still limiting widgets in the dashboard based on GoSquared plan, so we needed to restrict who had access to which resources). And every one of these subsequent requests also had an average response time of about 1.5 seconds.
The solution to this was to cache any fetched data that wasn’t likely to change. A user isn’t going to upgrade or downgrade their GoSquared subscription in the 2 seconds it takes for the dashboard to load its JS, so there’s no point fetching subscription data again if we’ve already fetched it once.
So, we went ahead and cached all the data we could, cutting response times down from 1.5 seconds to about 500ms on any requests which already had the data cached.

Step 3: Intelligent JS and CSS loading on the front-end

The front-end of the dashboard application has a lot of interconnected components. The JavaScript for the application falls into three main parts: libraries (such as jQuery, D3 etc.), the main application core, and widgets (each widget in the application is modularised and has its own code). Code in each of these parts is edited in very different ways: libraries are barely touched and are updated at most once a month; the core is changed several times a day; widgets can vary from receiving several changes in a day to not being touched in weeks.
Originally we bundled all our libraries into the core application bundle (which was included via a script tag on the page), and all of the widgets into a secondary bundle which was loaded dynamically. This meant that even with good cache control, any tiny change we made to the core code would mean browsers would have to download all of the (unchanged) library code, or any change to one widget would require downloading all of the widgets again.
One way around this problem would be to break each individual component into its own file and include them all individually — that way any files that don’t get changed frequently can sit in the browser’s HTTP cache and not be requested. The problem with this, though, is that there would be a lot of files, some of them incredibly small. And (especially on mobile browsers), the overhead of loading that many individual resources vastly outweights the extra overhead we had before of re-downloading unchanged content.
We eventually came up with a compromise solution based on Addy Osmani’s basket.js, using a combination of server-side script concatenation and localStorage for caching. In a nutshell, the page includes a lightweight loader script, which figures out which JS and CSS it has already cached and which needs to be fetched. The loader then requests all the resources it needs from the server in one request, and saves all the resources into localStorage under individual keys. This gives us a great compromise between cutting down the number of HTTP requests while still being able to maintain cacheability, and not re-downloading code unnecessarily when it hasn’t changed. Addtionally, after running a few benchmarks, we found that localStorage is (sometimes) actually faster than the native HTTP cache, especially on mobile browsers.
Along with this, we also switched all of our static (JS and CSS) asset loading to be served through CloudFront, Amazon Web Service’s content delivery network. This means content is served from the nearest possible geographic location to the user, cutting down request latency from as high as 2500ms (in places such as Singapore) to tens of milliseconds.
We also introduced some optimizations to prevent loading or storing duplicate code. For example, the Languages widget uses exactly the same code in Now, Trends and Ecommerce. By de-duplicating the caching and requests based on a digest of each resource’s contents, we were able to cut out unnecessary requests and storage.
With these intelligent changes to resource loading we were able to cut down the total number of HTTP requests necessary to render the dashboard to one (just the page itself), which meant that for users quickly switching between dashboards for different sites, each dashboard would load within a few seconds.
But we could do even better.

Step 4: Cut out the middle-man for fetching data

All the user, site and subscription data described in the first two steps was being fetched via a secure internal HTTP API to our internal account system, which at the time was written in some old, clunky, slow PHP. As part of our extensive rewrite of that whole system from PHP to Node, we were also able to cut out the internal HTTP component completely, instead including a node module directly in the dashboard application and requesting our databases directly. This allowed us much finer-grained control over exactly what data we were fetching, as well as eliminating a huge amount of overhead.
With this significant change, we were able to reduce our average response time (even without the caching described in Step 2), to 25ms.

Step 5: Do More on the Client

Thanks to all the changes we’d made up to this point, all that was different between different dashboards for different sites was a config object passed to the loader on initialization. It didn’t make sense, therefore, to be reloading the entire page when simply switching between sites or between Now and Trends, if all of the important resources had already been loaded. With a little bit of rearranging of the config object, we were able to include all of the data necessary to load any of the dashboards accessible to the user. Throw in some HTML5 History with pushState and popState, and we’re now able to switch between sites or dashboards without making a single HTTP request or even fetching scripts out of the localStorage cache. This means that switching between dashboards now takes a couple of hundred milliseconds, rather than several seconds.

What else?

So far all this has been about reducing load times and getting to a usable dashboard in the shortest time possible. But we’ve also done a lot to optimise the application itself to make sure it’s as fast as possible. In summary:
  • Don’t use big complex libraries if you don’t have to — for example, jQuery UI is great for flexibility and working around all manner of browser quirks, but we don’t support a lot of the older browsers so the code bloat is unnecessary. We were able to replace our entire usage of jQuery UI with some clever thinking and 100-or-so lines of concise JS (we also take advantage of things like HTML5’s native drag-and-drop).
  • Even respectable libraries have their weak spots — for example we use moment with moment-timezone for a lot of our date and time handling. However moment-timezone is woefully inefficient (especially on mobile) if you’re using it a lot. With a little bit of hacking we added a few optimizations of our own and made it much better for our use-case.
  • Slow animations make everything feel slow — a lot of studies have been posted about this in the past, and it really makes a difference. Simply reducing some CSS transition times from 500ms to 250ms, and cutting others out entirely, made the whole dashboard feel snappier and more responsive.
  • Instant visual feedback — one of the big things we found when using Trends was that switching between time frames just felt slow. It took under a second, but because there was a noticeable delay between clicking on the timeframe selector and anything actually happening, things felt broken. Fetching new data from our API is always going to take some time — it’s not going to be instant. So instead we introduced the loading spinner on each widget. Nothing is actually any faster, but the whole experience feels more responsive. There is immediate visual feedback when you click the button, so you know it’s working properly.
  • Flat design is actually really handy for performance — it may well just be a design trend, but cutting out superficial CSS gradients and box shadows does wonders for render performance. If the browser doesn’t have to use CPU power to render all these fancy CSS effects, you get an instant boost to render performance.
Now dashboard in action

What next?

Even after all these optimizations and tweaks, we’re well aware that there’s still plenty of room for improvement. Especially on mobile, where CPU power, memory, rendering performance, latency and bandwidth are all significantly more limited than they are on the desktop. We’ll continue improving everything we can, so stay tuned for further updates!

Tuesday, February 21, 2017

node.js jade view engine tutorials

/*views/shared/root.jade*/
doctype html
html(lang="en")
    head
        block head
            block title
                title Default Title
            meta(name="viewport", content="width=device-width, initial-scale=1.0")
            link(href='/#{loader.theme_favicon("default")}', rel='icon', type='image/png')
            link(href='/#{loader.theme_static("css/styles.css")}', rel='stylesheet', type='text/css')
            script(src='/#{loader.theme_static("js/scripts.js")}')
    body
        #body-wrapper
            block body

/*views/shared/site.jade*/
 
extends root
block body
    block variables
    div okey=#{body_class}
    #content-wrapper
        block content
    #footer-wrapper
        block footer
            - var imageName = new Date().getFullYear();
            span Copyright #{imageName} <br>


/*views/home/index.jade*/

extends ../shared/site
block variables
    -var body_class = 'i-am-the-home-page'
block append head
    script(src='/#{loader.theme_static("js/scripts123.js")}')
block title
    title #{model.title}
block content
    h1 Post's Header
    p Here's a list of all blog posts
mixin list-item
block footer
    //block comment
    h1 hello world
    //-invisible block comment
    h2 how are you?
    mixin header(title)
        div.container&attributes(attributes)
            h3.sectionHeader #{title}
            div.content(style="display: block")
                block
    +header('footer')(style="text-align:center; display: block; width: 500px;")
        p this is a footers paragraph
    -var jade_obj = require('jade');   
    -var list_view = loader.view_filename('login/partial/list.jade', router.langdir);   
    -if (loader.file_exists(list_view)) {
        -var html_str = jade_obj.renderFile(list_view, {list: model.list});
        div !{html_str}
    -} else {
        include ./partial/list
    -}


/*views/home/partial/list.jade*/

-var items = (list !== undefined ? list : model.list);
ul
    mixin htmlli(liitem)
        li(id="#{liitem}")= '!' + liitem
    -each item, i in items
        -if (items.length > 0)
            +htmlli(i + '. ' + item)
        -else
            include ./item

/*views/home/partial/item.jade*/

li= item

Friday, February 17, 2017

Node.js - use of module.exports as a constructor, Essential Node.js patterns and snippets

/***************************/ constructor version first

1.

function Login(base, req, res) {
    this._base = base;
    this._req = req;
    this._res = res;
    this.title = 'Login_title';
    this.description = 'Login_description';
}
Login.prototype = {
    constructor: Login,
    description: 'default_description',
    auth: function (args) {
        this._res.send(this.title + " => " + args + " , " + this.description);
    }
};
module.exports = Login;

/**************************/ constructor version second

2.

 class Login {
    constructor(base, req, res) {
        this.base = base;
        this.req = req;
        this.res = res;
        this.foo = 10;
    }
    auth(args) {
        this.res.json(this.foo + ';;;' + args);
    }
}
module.exports = Login;

****************************************************


var _constructor = require('./login');
var _object = new _constructor(base, req, res);
this.function = "auth";

if (typeof _object[this.function] === 'function') {
         _object[this.function]("passed args");
}


***********************************************************

1.2 Accessing global values from objects

// constructor
var Class = function(global, value2) {
  this.global = global;
}
// access using this.global in class methods

1.3 Factory pattern

// Constructor
var Class = function(value1, value2) { ... }
// Factory
Class.factory(value1) { return new Class(value1, "aaa"); }
// properties and methods
Class.prototype = { ... };

1.4 Sharing state between modules

var Common = {
  util: require('util'),
  fs:   require('fs'),
  path: require('path')
};

module.exports = Common;

// in other modules
var Common = require('./common.js');

1.5 Singleton class (added Feb 2011)

var Singleton = (function() {
   var private_variable = 'value';
   function private_function() {
      ...
   }
   function public_function() {
      ...
   }
  return {
      public_function: public_function
  };
})();




Saturday, February 11, 2017

node.js clustered express app with socket.io chat with redis-server boost

var express = require('express'),
        cluster = require('cluster'),
        net = require('net'),
        socketio = require('socket.io'),
        socket_redis = require('socket.io-redis');

var port = 80, num_processes = require('os').cpus().length;

if (cluster.isMaster) {
    // This stores our workers. We need to keep them to be able to reference
    // them based on source IP address. It's also useful for auto-restart,
    // for example.
    var workers = [];

    // Helper function for spawning worker at index 'i'.
    var spawn = function (i) {
        workers[i] = cluster.fork();

        // Optional: Restart worker on exit
        workers[i].on('exit', function (code, signal) {
            console.log('respawning worker', i);
            spawn(i);
        });
    };

    // Spawn workers.
    for (var i = 0; i < num_processes; i++) {
        spawn(i);
    }

    // Helper function for getting a worker index based on IP address.
    // This is a hot path so it should be really fast. The way it works
    // is by converting the IP address to a number by removing non numeric
    // characters, then compressing it to the number of slots we have.
    //
    // Compared against "real" hashing (from the sticky-session code) and
    // "real" IP number conversion, this function is on par in terms of
    // worker index distribution only much faster.
    var worker_index = function (ip, len) {
        var s = '';
        for (var i = 0, _len = ip.length; i < _len; i++) {
            if (!isNaN(ip[i])) {
                s += ip[i];
            }
        }
        return Number(s) % len;
    };

    // Create the outside facing server listening on our port.
    var server = net.createServer({pauseOnConnect: true}, function (connection) {
        // We received a connection and need to pass it to the appropriate
        // worker. Get the worker for this connection's source IP and pass
        // it the connection.
        var worker = workers[worker_index(connection.remoteAddress, num_processes)];
        worker.send('sticky-session:connection', connection);
    }).listen(port);

} else {
    /* don't use yet
     * var app = require('express')();
     var server = require('http').Server(app);
     var io = require('socket.io')(server);
     var redis = require('socket.io-redis');
     var http = app.listen(80, function () {
     console.log('ProcId : ' + process.pid + ' is listening to all incoming requests...');
     });*/
    // Note we don't use a port here because the master listens on it for us.
    var app = new express();

    // Here you might use middleware, attach routes, etc.
    app.use('/assets', express.static(__dirname + '/public'));
    app.get('/', function (req, res) {
        res.sendFile(__dirname + '/index.html');
    });

    // Don't expose our internal server to the outside.
    var server = app.listen(),
            io = socketio(server);

    // Tell Socket.IO to use the redis adapter. By default, the redis
    // server is assumed to be on localhost:6379. You don't have to
    // specify them explicitly unless you want to change them.
    io.adapter(socket_redis({host: 'localhost', port: 6379}));

    var online_members = 0;
    var chat_socket = io.of('/chat')
            .on('connection', function (client_socket) {
                var log = process.pid + ', ' + client_socket.id + ' : Connected';
                console.log(log);

                client_socket.on('login', function (data) {
                    online_members = online_members + 1;

                    client_socket.emit('ilogged', {id: client_socket.id, pid: process.pid, online_members: online_members});
                    client_socket.broadcast.emit('ulogged', {id: client_socket.id, pid: process.pid, online_members: online_members});

                    log = process.pid + ', ' + client_socket.id + ' : Logged';
                    console.log(log);
                });

                client_socket.on('message', function (data) {
                    var msg = process.pid + " : " + data;
                    client_socket.broadcast.emit('message', msg);

                    log = process.pid + ' : ' + data;
                    console.log(log);
                });

                client_socket.on('disconnect', function () {
                    online_members = online_members - 1;
                    client_socket.broadcast.emit('uclosed', {id: client_socket.id, pid: process.pid, online_members: online_members});

                    log = process.pid + ', ' + client_socket.id + ' : Disconnected';
                    console.log(log);
                });
            });

    console.log('ProcId : ' + process.pid + ' is listening to all incoming requests...');

    // Listen to messages sent from the master. Ignore everything else.
    process.on('message', function (message, connection) {
        if (message !== 'sticky-session:connection') {
            return;
        }

        // Emulate a connection event on the server by emitting the
        // event with the connection the master sent us.
        server.emit('connection', connection);

        connection.resume();
    });
}



scripts



var chat_client_start = function () { var logged = null; var chat_client = io.connect('http://BOR-PC/chat'); chat_client.on('connect', function () { $('#messages').append($('
  • ').text('Logging...')); if (logged === null) { chat_client.emit("login", "I am logging..."); } }); chat_client.on('ilogged', function (data) { logged = data; var txt = "I am Logged: " + data.pid + ', ' + data.id + ', c:' + data.online_members; $('#messages').append($('


  • ').text(txt)); }); chat_client.on('ulogged', function (data) { var txt = "User Logged: " + data.pid + ', ' + data.id + ', c:' + data.online_members; $('#messages').append($('
  • ').text(txt)); }); chat_client.on('uclosed', function (data) { var txt = "User Closed: " + data.pid + ', ' + data.id + ', c:' + data.online_members; $('#messages').append($('
  • ').text(txt)); }); chat_client.on('message', function (msg) { $('#messages').append($('
  • ').text(msg)); }); chat_client.on('disconnect', function () { logged = null; // chat_client.disconnect(); // chat_client.removeAllListeners('connect'); $('#messages').append($('
  • ').text('Server disconnected.')); $('#messages').append($('
  • ').text('Reconnecting...')); setTimeout(function () { chat_client_start(); }, 5000); }); $('form').submit(function () { var msg_txt = $('#msg_txt').val(); $('#messages').append($('
  • ').text(msg_txt)); chat_client.emit('message', msg_txt); $('#msg_txt').val(''); return false; }); }; chat_client_start();
  •