Ejemplo n.º 1
0
        /// <summary>
        /// Generate Sql statements from the Keys-Values
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="client"></param>
        /// <param name="keys"></param>
        /// <param name="values"></param>
        /// <returns></returns>
        private static IEnumerable <KeyValuePair <string, KeyValuePair <byte[], long> > > GenerateSqlFrom(SqlDataSender sender, RedisClient client, byte[][] keys, byte[][] values)
        {
            var typeKeyValuePairs = new List <KeyValuePair <string, byte[][]> >();

            for (int i = 0; i < keys.Length; i++)
            {
                byte[]   keyBytes       = keys[i];
                byte[]   headBytes      = values[i];
                string   entityTypeKey  = RedisConnectionPool.ToStringKey(keyBytes);
                string[] entityKeys     = entityTypeKey.Split(',')[0].Split('_');
                string   typeName       = entityKeys[0];
                byte[]   entityKeyBytes = RedisConnectionPool.ToByteKey(entityKeys[1]);
                typeKeyValuePairs.Add(new KeyValuePair <string, byte[][]>(typeName, new[] { entityKeyBytes, keyBytes, headBytes })
                                      );
            }
            var sqlList   = new List <KeyValuePair <string, KeyValuePair <byte[], long> > >();
            var typeGroup = typeKeyValuePairs.GroupBy(p => p.Key);

            foreach (var g in typeGroup)
            {
                var typeName = g.Key;
                try
                {
                    string entityParentKey = RedisConnectionPool.GetRedisEntityKeyName(typeName);
                    string asmName         = "";
                    var    enitityAsm      = EntitySchemaSet.EntityAssembly;
                    if (enitityAsm != null)
                    {
                        asmName = "," + enitityAsm.GetName().Name;
                    }

                    Type type = Type.GetType(string.Format("{0}{1}", RedisConnectionPool.DecodeTypeName(typeName), asmName), false, true);
                    if (type == null)
                    {
                        //调试模式下type为空处理
                        type = enitityAsm != null?enitityAsm.GetType(RedisConnectionPool.DecodeTypeName(typeName), false, true) : null;

                        if (type == null)
                        {
                            throw new ArgumentTypeException(string.Format("Get entity \"{0}\" type is null", entityParentKey));
                        }
                    }
                    var keyBuffers   = g.Select(p => p.Value[0]).ToArray();
                    var headBuffers  = g.Select(p => p.Value[2]).ToArray();
                    var valueBuffers = client.HMGet(entityParentKey, keyBuffers);

                    for (int i = 0; i < keyBuffers.Length; i++)
                    {
                        string keyCode   = RedisConnectionPool.ToStringKey(keyBuffers[i]);
                        var    buffer    = valueBuffers != null && valueBuffers.Length > i ? valueBuffers[i] : null;
                        var    headBytes = headBuffers[i];
                        int    identity;
                        int    state;
                        DecodeHeadBytes(headBytes, out identity, out state);

                        AbstractEntity entity = null;
                        if (state == 1 && buffer == null)
                        {
                            //entity remove ops
                            entity          = type.CreateInstance(new object[0]) as AbstractEntity;
                            entity.IsDelete = true;
                            entity.SetKeyValue(keyCode, typeName);
                        }
                        else if (buffer != null)
                        {
                            entity = _serializer.Deserialize(buffer, type) as AbstractEntity;
                        }
                        if (entity != null)
                        {
                            if (state == 1)
                            {
                                entity.IsDelete = true;
                            }
                            SqlStatement statement = sender.GenerateSqlQueue(entity);
                            if (statement == null)
                            {
                                throw new Exception(string.Format("Generate sql of \"{0}\" entity error", typeName));
                            }
                            var    sqlValueBytes = ProtoBufUtils.Serialize(statement);
                            string sqlQueueKey   = SqlStatementManager.GetSqlQueueKey(statement.IdentityID);
                            sqlList.Add(new KeyValuePair <string, KeyValuePair <byte[], long> >(sqlQueueKey,
                                                                                                new KeyValuePair <byte[], long>(sqlValueBytes, DateTime.Now.Ticks)));
                        }
                        else
                        {
                            throw new Exception(string.Format("Get \"{0}\" entity is null, keycode:{1},buffer len:{2},state:{3}",
                                                              typeName, keyCode, buffer == null ? -1 : buffer.Length, state));
                        }
                    }
                }
                catch (Exception er)
                {
                    TraceLog.WriteError("FindEntityFromRedis {0} error:{1}", typeName, er);
                    var errorKeys   = g.Select(p => p.Value[1]).ToArray();
                    var errorValues = g.Select(p => p.Value[2]).ToArray();
                    client.HMSet(SqlSyncWaitErrirQueueKey, errorKeys, errorValues);
                }
            }
            return(sqlList);
        }