Example #1
0
// to come true ExecCore interface
func (d *InsertDML) Do() (interface{}, error) {
	d.Mut.Lock()
	defer d.Mut.Unlock()

	// get the relation true table.
	var err error
	var shardTables []*schema.MysqlShardTable
	var curTable *schema.MysqlTable
	for i := 0; i < len(schema.Tables); i++ {
		if schema.Tables[i].Name == d.TableName {
			curTable = schema.Tables[i]
			shardTables = curTable.Shards
			break
		}
	}
	if shardTables == nil {
		return nil, errors.New("no found any one this table " + d.TableName)
	}

	// get the last true table.
	tableLen := len(shardTables)
	var table *schema.MysqlShardTable

	for i := 0; i < tableLen; i++ {
		if shardTables[i].RowTotal < uint64(5000000) {
			table = shardTables[i]
			break
		}
	}

	if table == nil {
		// to build new shard table
		table, err = curTable.BuildNewShardTable()
		if err != nil {
			return nil, err
		}
	}

	// parse the sql, to find the auto increment key,
	// then change its' value to table global id.
	sql, params, err := curTable.ParseMergeInsertGlobalId(d.Sql, table)
	if err != nil {
		return nil, err
	}

	master := host.GetBetterHost(table.ShardDB.HostGroup.Master, "master")
	conn, err := master.ConnToDB(table.ShardDB.Name)
	if err != nil {
		conn.Close()
		return nil, err
	}

	stmt, err := conn.Prepare(sql)
	if err != nil {
		conn.Close()
		return nil, err
	}

	res, err := stmt.Exec(params...)
	if err != nil {
		conn.Close()
		return nil, err
	}

	stmt.Close()
	conn.Close()

	curTable.RowTotal++
	curTable.UpdateToRedisDB()

	return res.LastInsertId()
}