func NewEngineFromConfig(config string) (*Engine, error) {
	var cluster clusterConfig
	file, err := os.Open(config)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	config = strings.ToLower(config)
	if strings.HasSuffix(config, ".json") {
		d := json.NewDecoder(file)
		if err = d.Decode(&cluster); err != nil {
			return nil, err
		}
	} else if strings.HasSuffix(config, ".xml") {
		d := xml.NewDecoder(file)
		if err = d.Decode(&cluster); err != nil {
			return nil, err
		}
	} else {
		return nil, fmt.Errorf("the file format of config file is not be supported.")
	}
	return NewEngine(cluster.Driver, cluster.Cluster), nil
}
NewEngineFromConfig allows Engine can be created from config file.
Currently, the config file could be xml or json file.
/*
json config:
{
"driver": "mssql",
"cluster": {
"total_groups": 10,
"groups": [
{
"range_from": 0,
"range_to": 4,
"is_default": true,
"name": "group1",
"nodes": [
{
"name": "g1_master",
"conn_string": "server=localhost;database=Test;user id=user;password=pwd",
"node_type": "master"
},
{
"name": "g1_node1",
"conn_string": "server=localhost;database=Test;user id=user;password=pwd",
"node_type": "slave",
"weight": 2
}
]
},
{
"range_from": 5,
"range_to": 9,
"name": "group2",
"nodes": [
{
"name": "g2_master",
"conn_string": "server=localhost;database=Test;user id=user;password=pwd",
"node_type": "master"
},
{
"name": "g2_node1",
"conn_string": "server=localhost;database=Test;user id=user;password=pwd",
"node_type": "slave",
"weight": 2
}
]
}
]
}
}

xml config:
<ClusterConfig>
<Driver>mssql</Driver>
<Cluster>
<TotalGroups>10</TotalGroups>
<Groups>
<Group>
<Name>group1</Name>
<RangeFrom>0</RangeFrom>
<RangeTo>4</RangeTo>
<Nodes>
<Node>
<Name>g1_master</Name>
<ConnStr>database connection string</ConnStr>
<NodeType>master</NodeType>
</Node>
<Node>
<Name>g1_node</Name>
<ConnStr>database connection string</ConnStr>
<NodeType>slave</NodeType>
<Weight>2</Weight>
</Node>
</Nodes>
</Group>
<Group>
<Name>group1</Name>
<RangeFrom>5</RangeFrom>
<RangeTo>9</RangeTo>
<Nodes>
<Node>
<Name>g2_master</Name>
<ConnStr>database connection string</ConnStr>
<NodeType>master</NodeType>
</Node>
<Node>
<Name>g2_node</Name>
<ConnStr>database connection string</ConnStr>
<NodeType>slave</NodeType>
<Weight>2</Weight>
</Node>
</Nodes>
</Group>
</Groups>
</Cluster>
</ClusterConfig>
package shorm
import (
	"encoding/json"
	"encoding/xml"
	"fmt"
	"log"
	"os"
	"strings"
	"sync"
)
var sqlGenDict = map[string]SqlGenerator{
	"mssql":    NewMSSqlGenerator(),
	"mysql":    newBaseGenerator(),
	"mymysql":  newBaseGenerator(),
	"postgres": newBaseGenerator(),
	"sqlite":   newBaseGenerator(),
}
type emptyLogger struct {
}
func (e *emptyLogger) Write(b []byte) (n int, err error) {
	return
}
type Engine struct {
	cluster *Cluster
	Logger  *log.Logger
	pool    *sync.Pool
	driver  string
}
func NewEngine(driver string, cluster *Cluster) *Engine {
	e := &Engine{
		cluster: cluster,
		pool:    &sync.Pool{},
		driver:  driver,
		Logger:  log.New(&emptyLogger{}, "", 0),
	}
	e.cluster.RealGroups = len(e.cluster.Groups)
	e.pool.New = func() interface{} { return &Session{} }
	return e
}
func NewEngineV2(driver, connstr string) *Engine {
	cluster := &Cluster{TotalGroups: 1}
	cluster.Groups = append(cluster.Groups, &DbGroup{
		Nodes: []*DbNode{
			{
				Name:    "master",
				ConnStr: connstr,
				Type:    NodeType_Master,
			}},
	})
	return NewEngine(driver, cluster)
}
type clusterConfig struct {
	XMLName xml.Name `json:"-" xml:"ClusterConfig"`
	Driver  string   `json:"driver"`
	Cluster *Cluster `json:"cluster"`
}