Saturday, May 28, 2016

char 烤焦 - partially burn (an object) so as to blacken its surface.

char 烤焦 - partially burn (an object) so as to blacken its surface.

It will turn dark if no quick fry.

牛排烤焦

lightly toasted

Friday, May 27, 2016

Turn Off Number Input Spinners

Turn Off Number Input Spinners:

input[type=number]::-webkit-inner-spin-button, 
input[type=number]::-webkit-outer-spin-button { 
  -webkit-appearance: none; 
  margin: 0; 
}

To style Number Input Spinners:

input[type=number]::-webkit-inner-spin-button { 
    -webkit-appearance: none;
    cursor:pointer;
    display:block;
    width:8px;
    color: #333;
    text-align:center;
    position:relative;
}

input[type=number]::-webkit-inner-spin-button:before,
input[type=number]::-webkit-inner-spin-button:after {
    content: "^";
    position:absolute;
    right: 0;
    font-family:monospace;
    line-height:
}

input[type=number]::-webkit-inner-spin-button:before {
    top:0px;
}

input[type=number]::-webkit-inner-spin-button:after {
    bottom:0px;
    -webkit-transform: rotate(180deg);
}

Reference:

https://css-tricks.com/snippets/css/turn-off-number-input-spinners/

Thursday, May 26, 2016

OCD driven 強迫症

Obsessive–compulsive disorder (OCD) is a mental disorder where people feel the need to check things repeatedly, perform certain routines repeatedly (called "rituals"), or have certain thoughts repeatedly.

make div position center

make div position center

#test {
  z-index: 18005;
  top: calc(50vh - 100px) !important;
  left: calc(50vw - 150px) !important;
  width: calc(20% - 20px);
}

Wednesday, May 25, 2016

jQuery UI Multicolumn Autocomplete Widget Plugin 2.1

custom.mcautocomplete.js:

/*
 * jQuery UI Multicolumn Autocomplete Widget Plugin 2.1
 * Copyright (c) 2012-2014 Mark Harmon
 *
 * Depends:
 * - jQuery UI Autocomplete widget
 *
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 */
$.widget('custom.mcautocomplete', $.ui.autocomplete, {
  _create: function () {
    this._super();
    this.widget().menu("option", "items", "> :not(.ui-widget-header)");
  },
  _renderMenu: function (ul, items) {
    var that = this;

    if (this.options.showHeader) {
      row = $('<div class="row ui-widget-header" style="position: fixed; z-index: 18003; width: 600px; margin: 0px;">');

      $.each(this.options.columns, function (index, column) {
        row.append('<div class="' + column.colClass + '">' + column.text + '</div>');
      });

      ul.append(row);
    }

    $.each(items, function (index, item) {
      that._renderItemData(ul, item);
    });
  },
  _renderItem: function (ul, item) {
    row = $('<div class="row">');

    if (this.options.showHeader) {
      $.each(this.options.columns, function (index, column) {
        row.append('<div class="' + column.colClass + '">' + item[column.field] + '</div>');
      });
    }

    return $('<li>')
      .attr('data-value', item.value)
      //.data('ui-autocomplete-item', item)
      .append(row)
      .appendTo(ul);
  }
});

Example:

    $('#ItemNum').mcautocomplete({
      showHeader: true,
      columns: [
        {field: 'ItemNum', text: 'ItemNum', colClass: 'col-lg-6'},
        {field: 'ItemName', text: 'ItemName', colClass: 'col-lg-6'},
      ],
      minLength: 1,
      autoFocus: true,
      source: function (request, response) {
        var optObj = {};
        optObj.ItemNum = request.term;

        $.ajax({url: '/index?act=ListItemInventory', data: JSON.stringify(optObj),
          success: function(dataObj) {
            if (dataObj.Status == true) {
              response(dataObj.ItemInventoryArr);
            } else {
              response([]);
            }
          },
          error: function(dataObj) {
            response([]);
          },
        });
      },
      create: function(event, ui) {
        $(this).mcautocomplete("widget").css({
          height: 200,
          "overflow-x": "hidden",
          "overflow-y": "scroll",
        });
        $(this).data('custom-mcautocomplete')._resizeMenu = function() {
          this.menu.element.outerWidth(600);
        };
      },
      select: function(event, ui) {
        $(this).val(ui.item.Item.ItemNum);
      },
      close: function(event, ui) {
      },
    });

Reference:

http://jsfiddle.net/alforno/g4stl/

Tuesday, May 24, 2016

This example shows how to use jQuery UI autocomplete Extension Points to customize auto-complete drop-down content

This example shows how to use jQuery UI autocomplete Extension Points to customize auto-complete drop-down content.

Using ui-autocomplete instead should solve your issue.

$("#lexicon-search-input")
    .autocomplete({
    ...
    }).data("ui-autocomplete")._renderItem = customItemRenderer;

See the documentation for a tutorial on how to use _renderItem (especially the source code)

If you want to create the _renderItem function for multiple autocompletes with class yourClass just use it in the createevent

$('.yourClass').autocomplete({
    create: function() {
        $(this).data('ui-autocomplete')._renderItem ....
    }
});

Full example:


  // global ajax setting.
  $.ajaxSetup({
    type: 'post',
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    timeout: 60 * 1000,
    headers: {
      Authorization: token,
    },
  });

function BindLine(LineNum) {
    $('#Line_' + LineNum + '_ItemNum').autocomplete({
      minLength: 2,
      source: function (request, response) {
        var optObj = {};
        optObj.ItemNum = request.term;

        $.ajax({url: '/test?act=ListItem', data: JSON.stringify(optObj),
          success: function(dataObj) {
            if (dataObj.Status == true) {
              response(dataObj.PostListItemLineArr);
            } else {
              response([]);
            }
          },
          error: function(dataObj) {
            response([]);
          },
        });
      },
      create: function() {
        $(this).autocomplete("widget").css({
          height: 200,
          "overflow-x": "hidden",
          "overflow-y": "scroll",
        });

        $(this).data('ui-autocomplete')._renderItem = function(ul, item) {
          var html = '<div class="row">'
              + '<div class="col-lg-2">' + item.ItemNum + '</div>'
              + '<div class="col-lg-8">' + item.ItemName + '</div>'
              + '<div class="col-lg-2">' + item.InventoryQty + '</div>'
            + '</div>';
          return $("<li>")
            .append(html)
            .appendTo(ul);
        };

        $(this).data('ui-autocomplete')._resizeMenu = function() {
          this.menu.element.outerWidth(500);
        };
      },
      close: function(event, ui) {
        var itemNum = $(this).val();
      },
      select: function(event, ui) {
        $(this).val(ui.item.ItemNum);
      },
    });
}

Cannot set property '_renderItem' of undefined jQuery UI autocomplete


And now, with jQuery-2.0.0, it's the name of your new module, but replacing the "." (dot) by the "-" (dash) :

jQuery.widget ('custom.catcomplete', jQuery.ui.autocomplete, {
    '_renderMenu': function (ul, items) {
        // some work here
    }
});

$this.catcomplete({
    // options
}).data('custom-catcomplete')._renderItem = function (ul, item) {}

Reference:

http://stackoverflow.com/questions/17568630/jqueryui-version-1-10-autocomplete-how-to-set-renderitem

http://stackoverflow.com/questions/16371204/how-to-change-rendering-of-dropdown-in-jquery-ui-autocomplete-attached-to-a-clas/16372823#16372823

http://stackoverflow.com/questions/9513251/cannot-set-property-renderitem-of-undefined-jquery-ui-autocomplete-with-html

Thursday, May 19, 2016

cannot take the address of

To understand why this isn't possible, it is helpful to think about what an interface variable actually is. An interface value takes up two words, with the first describing the type of the contained value, and the second either (a) holding the contained value (if it fits within the word) or (b) a pointer to storage for the value (if the value does not fit within a word).

The important things to note are that (1) the contained value belongs to the interface variable, and (2) the storage for that value may be reused when a new value is assigned to the variable. Knowing that, consider the following code:

var v interface{}
v = int(42)
p := GetPointerToInterfaceValue(&v) // a pointer to an integer holding 42
v = &SomeStruct{...}
Now the storage for the integer has been reused to hold a pointer, and *p is now an integer representation of that pointer. You can see how this has the capacity to break the type system, so Go doesn't provide a way to do this (outside of using the unsafe package).

If you need a pointer to the structs you're storing in a list, then one option would be to store pointers to the structs in the list rather than struct values directly. Alternatively, you could pass *list.Element values as references to the contained structures.

Interface values are not necessarily addressable. For example,

package main

import "fmt"

func main() {
    var i interface{}
    i = 42
    // cannot take the address of i.(int)
    j := &i.(int)
    fmt.Println(i, j)
}

Address operators

For an operand x of type T, the address operation &x generates a pointer of type *T to x. The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x may also be a composite literal.

Reference:

http://stackoverflow.com/questions/15518919/take-address-of-value-inside-an-interface

http://golang.org/ref/spec#Address_operators

https://groups.google.com/forum/#!topic/golang-nuts/vPHiJwxVN98/discussion

Saturday, May 14, 2016

innodb_lock_wait_timeout increase timeout

To explain GLOBAL vs SESSION for VARIABLES: The GLOBAL value is used to initialize the SESSION value when your connection starts. After that, you can change the SESSION value to affect what you are doing. And changing the GLOBAL value has no effect on your current connection.

SET GLOBAL innodb_lock_wait_timeout = 10;
SELECT @@innodb_lock_wait_timeout;

SET SESSION innodb_lock_wait_timeout = 10;
SELECT @@innodb_lock_wait_timeout;

SHOW VARIABLES WHERE Variable_name REGEXP 'lock_wait';

Reference:

http://stackoverflow.com/questions/28735473/innodb-lock-wait-timeout-increase-timeout

Tuesday, May 10, 2016

Show query log in MySQL

SET global general_log = 'ON';
#SET global general_log = 'OFF';

#SET global log_output = 'TABLE';
SET global log_output = 'FILE';

SHOW VARIABLES WHERE variable_name REGEXP 'general_log|log_output' ;

SELECT * FROM mysql.general_log;

Saturday, May 7, 2016

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED

To check or set the global and session transaction isolation levels at runtime by using the tx_isolation system variable:

SELECT @@GLOBAL.tx_isolation, @@tx_isolation;
SET GLOBAL tx_isolation='READ-COMMITTED';
SET SESSION tx_isolation='READ-COMMITTED';

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
SELECT * FROM users WHERE uid = 1 FOR UPDATE;
COMMIT;

# vim /etc/my.cnf

[mysqld]
transaction-isolation = READ-COMMITTED

Reference:

https://dev.mysql.com/doc/refman/5.5/en/set-transaction.html

https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_tx_isolation

https://www.percona.com/blog/2012/03/27/innodbs-gap-locks/

Run execute MySQL command in shell under console

Run execute MySQL command in shell under console

To debug InnoDB lock waits. Show how many rows are locked (look under transaction):

# mysql -u root -p -e 'SHOW ENGINE INNODB STATUS\G'


------------
TRANSACTIONS
------------
Trx id counter 381
Purge done for trx's n:o < 37F undo n:o < 0
History list length 39
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started
MySQL thread id 84, OS thread handle 0x7f5b66aff700, query id 975 localhost root
SHOW ENGINE INNODB STATUS
---TRANSACTION 0, not started
MySQL thread id 50, OS thread handle 0x7f5b66c23700, query id 838 192.168.6.112 jun
---TRANSACTION 32E, not started
MySQL thread id 33, OS thread handle 0x7f5b8c04a700, query id 693 192.168.6.112 jun
---TRANSACTION 35F, not started
MySQL thread id 31, OS thread handle 0x7f5b66c6c700, query id 518 192.168.6.112 jun
---TRANSACTION 340, not started
MySQL thread id 28, OS thread handle 0x7f5b66bda700, query id 381 192.168.6.112 jun
---TRANSACTION 380, ACTIVE 1 sec starting index read
mysql tables in use 2, locked 2
LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s)
MySQL thread id 83, OS thread handle 0x7f5b66b91700, query id 973 127.0.0.1 go_erp statistics
SELECT   SO.idOrder , SOLine.changed , SOLine.orderQty FROM SO INNER JOIN SOLine ON SO.idOrder = SOLine.idOrder WHERE SO.idOrder = 1 ORDER BY SO.idOrder FOR UPDATE
------- TRX HAS BEEN WAITING 1 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 323 n bits 72 index `PRIMARY` of table `go_erp`.`SO` trx id 380 lock_mode X locks rec but not gap waiting
------------------
---TRANSACTION 37F, ACTIVE 2 sec
5 lock struct(s), heap size 1248, 3 row lock(s), undo log entries 1
MySQL thread id 82, OS thread handle 0x7f5b66b48700, query id 969 127.0.0.1 go_erp
----------------------------

# mysql -u root -p -e 'test.sql'

Install innotop:

# yum install innotop

Reference:

http://www.xaprb.com/blog/2007/09/18/how-to-debug-innodb-lock-waits/

Friday, May 6, 2016

select data from database

The following solution allows you to refer to the field by field name instead of index. It's more like PHP style:

Table definition:

CREATE TABLE `salesOrder` (
  `idOrder` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `uid` int(10) unsigned NOT NULL,
  `changed` datetime NOT NULL,
  PRIMARY KEY (`idOrder`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

main.go:

package main

import (
        "database/sql"
        "encoding/json"
        "fmt"
        _ "github.com/go-sql-driver/mysql"
        "log"
        "reflect"
        "strings"
)

var (
        db *sql.DB
)

func initDB() {
        var err error

        // The database/sql package manages the connection pooling automatically for you.
        // sql.Open(..) returns a handle which represents a connection pool, not a single connection.
        // The database/sql package automatically opens a new connection if all connections in the pool are busy.
        // Reference: http://stackoverflow.com/questions/17376207/how-to-share-mysql-connection-between-http-goroutines
        db, err = sql.Open("mysql", "MyUser:MyPassword@tcp(localhost:3306)/MyDB")
        //db, err = sql.Open("mysql", "MyUser:MyPassword@tcp(localhost:3306)/MyDB?tx_isolation='READ-COMMITTED'") // optional

        if err != nil {
                log.Fatalf("Error on initializing database connection: %v", err.Error())
        }

        // Open doesn't open a connection. Validate DSN data:
        err = db.Ping()

        if err != nil {
                log.Fatalf("Error on opening database connection: %v", err.Error())
        }
}

func StrutToSliceOfFieldAddress(s interface{}) []interface{} {
        fieldArr := reflect.ValueOf(s).Elem()

        fieldAddrArr := make([]interface{}, fieldArr.NumField())

        for i := 0; i < fieldArr.NumField(); i++ {
                f := fieldArr.Field(i)
                fieldAddrArr[i] = f.Addr().Interface()
        }

        return fieldAddrArr
}

func testSelectMultipleRowsV3(optArr map[string]interface{}) {
        // queries
        query := []string{}
        param := []interface{}{}

        if val, ok := optArr["idOrder"]; ok {
                query = append(query, "salesOrder.idOrder >= ?")
                param = append(param, val)
        }

        // The first character of the field name must be in upper case. Otherwise, you would get:
        // panic: reflect.Value.Interface: cannot return value obtained from unexported field or method
        var sqlField = struct {
                IdOrder int
                Uid     int
                Changed string
        }{}

        var rowArr []interface{}

        sqlFieldArrPtr := StrutToSliceOfFieldAddress(&sqlField)

        sql := "SELECT "
        sql += "  salesOrder.idOrder "
        sql += ", salesOrder.uid "
        sql += ", salesOrder.changed "
        sql += "FROM salesOrder "
        sql += "WHERE " + strings.Join(query, " AND ") + " "
        sql += "ORDER BY salesOrder.idOrder "

        stmt, err := db.Prepare(sql)
        if err != nil {
                log.Printf("Error: %v", err)
        }
        defer stmt.Close()

        rows, err := stmt.Query(param...)

        if err != nil {
                log.Printf("Error: %v", err)
        }

        defer rows.Close()

        if err != nil {
                log.Printf("Error: %v", err)
        }

        //sqlFields, err := rows.Columns()

        for rows.Next() {
                err := rows.Scan(sqlFieldArrPtr...)

                if err != nil {
                        log.Printf("Error: %v", err)
                }

                // Show the type of each struct field
                f1 := reflect.TypeOf(sqlField.IdOrder)
                f2 := reflect.TypeOf(sqlField.Uid)
                f3 := reflect.TypeOf(sqlField.Changed)
                fmt.Printf("Type: %v\t%v\t%v\n", f1, f2, f3)

                // Show the value of each field
                fmt.Printf("Row: %v\t%v\t%v\n\n", sqlField.IdOrder, sqlField.Uid, sqlField.Changed)

                rowArr = append(rowArr, sqlField)
        }

        if err := rows.Err(); err != nil {
                log.Printf("Error: %v", err)
        }

        // produces neatly indented output
        if data, err := json.MarshalIndent(rowArr, "", " "); err != nil {
                log.Fatalf("JSON marshaling failed: %s", err)
        } else {
                fmt.Printf("json.MarshalIndent:\n%s\n\n", data)
        }
}

func main() {
        initDB()
        defer db.Close()

        // this example shows how to dynamically assign a list of field name to the rows.Scan() function.
        optArr := map[string]interface{}{}
        optArr["idOrder"] = 1
        testSelectMultipleRowsV3(optArr)
}

Sample output:

# go run main.go

Type: int       int     string
Row: 1  1       2016-05-06 20:41:06

Type: int       int     string
Row: 2  2       2016-05-06 20:41:35

json.MarshalIndent:
[
 {
  "IdOrder": 1,
  "Uid": 1,
  "Changed": "2016-05-06 20:41:06"
 },
 {
  "IdOrder": 2,
  "Uid": 2,
  "Changed": "2016-05-06 20:41:35"
 }
]

Sunday, May 1, 2016

Data sanitization

Data sanitization

Code injection is the exploitation of a computer bug that is caused by processing invalid data. Injection is used by an attacker to introduce (or "inject") code into a vulnerable computer program and change the course of execution. The result of successful code injection is often disastrous (for instance: code injection is used by some computer worms to propagate).

Reference:

https://en.wikipedia.org/wiki/Code_injection#Preventing_code_injection

Creates a password hash

Creates a password hash:

password_hash: http://php.net/manual/en/function.password-hash.php

crypt: http://php.net/manual/en/function.crypt.php

hash_pbkdf2: http://php.net/manual/en/function.hash-pbkdf2.php