发布 redis 扩展库

By terrorist at 2021-12-25 • 0人收藏 • 743人看过

https://gitcode.net/vmax666/aaz-aardio

7 个回复 | 最后更新于 2022-07-02
2021-12-25   #1

github又打不开了

大T, 你这个和扩展库里那个hiredis有啥区别?

2021-12-25   #2

多刷几次又打开了......


为了方便git不方便上的人看, 代码展示如下, 切记最新代码还是从github链接那里下载.

库代码如下:

import wsock.tcp.client;

namespace aaz;
class redis{
	ctor(){
		..table.gc(this, "close")
	};
	close = function(){
		if(this.tcpClient){
			this.tcpClient.close();
			this.tcpClient = null;
		}
	};
	connect = function(ip="127.0.0.1", port=6379, timeout=3){
		this.tcpClient := ..wsock.tcp.client();
		if(!this.tcpClient.connectTimeout(ip, port, timeout)){
			return false, "连接服务器失败"; 
		}
		return true;
	};
	setTimeouts = function(send=5000,receive=5000){
		if(this.tcpClient){
			return this.tcpClient.setTimeouts(send, receive); 
		}
	};
	command = function(...){
		var args = {...}; 
		
		var ptr = ..raw.realloc(1);
		// *<参数数量> CR LF
		ptr = ..raw.concat(ptr, resp.arrays ++ #args ++ resp.CRLF); 
		
		// $<参数 i 的字节数量> CR LF
		// <参数 i 的数据> CR LF
		for(i=1;#args;1){
			ptr = ..raw.concat(ptr, 
				resp.bulkStrings ++ #args[i] ++ resp.CRLF ++ 
				args[i] ++ resp.CRLF
			);
		}

		var ok, err = this.tcpClient.write(..raw.tostring(ptr));
		ptr = ..raw.realloc(0, ptr);
		
		if(!ok){
			this.tcpClient.close();
			return false, err; 
		}
		return this.readReply(); 
	};
	readReply = function(){
		// 无参数表示读取一行,包含尾部的 CRLF,但返回的数据不包含尾部的 CRLF 这2个字节
		var line = this.tcpClient.read();
		if(!line){
			 // 获取错误代码, 10060 超时  10054 中断*/
			var errCode = ::Ws2_32.WSAGetLastError();
			// 超时关闭连接
			if(errCode == 10060){
				this.tcpClient.close();
			}
			return false, errCode; 
		}
		
		var prefix = ..string.charCodeAt(line); 
		select(prefix) {
			case 43/*status + Simple Strings*/ {
				return ..string.slice(line, 2); 
			}
			case 45/*error - 当用户对不正确的数据类型执行命令, 或者执行一个不存在的命令。收到错误回复时产生一个异常。*/ { 
				var err = ..string.slice(line, 2)
				error(err, 2)
			}
			case 58/*Integers : 必须能够用 64 位有符号整数表示*/ {
				return tonumber(..string.slice(line, 2)); 
			} 
			case 36/*bulk $ "$6\r\nfoobar\r\n" 批量字符串是用来表示一个单一的二进制安全字符串,长度可达512MB*/{
				var size = tonumber(..string.slice(line, 2));
				// 如果被请求的值不存在, 那么批量回复会将特殊值 -1 用作回复的长度值
				// 客户端应该返回空对象,而不是空字符串
				if(size<0){
					return null; 
				}
				
				var data = this.tcpClient.read(size)
				if(!data){
					var errCode = ::Ws2_32.WSAGetLastError();
					if(errCode == 10060){
						this.tcpClient.close();
					}
					return false, errCode; 	
				}
				
				// 读末尾的 CRLF
				var dummy = this.tcpClient.read(2)
				if(!dummy){
					var errCode = ::Ws2_32.WSAGetLastError();
					if(errCode == 10060){
						this.tcpClient.close();
					}
					return false, errCode; 	
				}
				return data; 
			}
			case 42/*multi bulk * 多条批量回复是由多个回复组成的数组, 数组中的每个元素都可以是任意类型的回复, 包括多条批量回复本身。*/{
				var n = tonumber(..string.slice(line, 2));
				/*
				无内容的多条批量回复(null multi bulk reply)也是存在的, 
				比如当 BLPOP 命令的阻塞时间超过最大时限时, 
				它就返回一个无内容的多条批量回复, 这个回复的计数值为 -1
				
				客户端库应该区别对待空白多条回复和无内容多条回复: 
				当 Redis 返回一个无内容多条回复时, 客户端库应该返回一个 null 对象, 而不是一个空数组。
				*/
				if(n<0){
					return null; 
				}
				var tab = {};
				for(i=1;n;1){
					var res, err = this.readReply();	
					if(res){
						tab[i] = res;
					}
					elseif(res === false){
						return false, err; 
					}
					elseif(res === null){
						tab[i] = null;
					}	
				}
				return tab; 
			}
		}			
	};
	set = function(key, value){
		var ret, err = this.command("set", key, value);
		return ret == "OK", err; 
	};
	//  当 key 不存在
	setnx = function(key, value){
		var ret, err = this.command("SETNX", key, value);
		return ret == 1, err; 
	};
	// 指定过期时间,秒为单位
	setex = function(key, value, seconds){
		var ret, err = this.command("SETEX", key, tostring(seconds), value); 
		return ret == "OK", err; 
	};
	// 指定过期时间,毫秒为单位
	psetex = function(key, value, seconds){
		var ret, err = this.command("PSETEX", key, tostring(seconds), value); 
		return ret == "OK", err; 
	};
	ttl = function(key){
		return this.command("TTL", key); 
	};
	pttl = function(key){
		return this.command("PTTL", key); 
	};
	// 如果 key 中存储的值不是字符串,则会返回错误,因为 GET 仅处理字符串值
	get = function(key, value){
		return this.command("get", key);
	};
	/*
	第一次设置 key 返回 field 数量
	重复设置 key 返回 0 
	*/
	hset = function(key, field, value, ...){
		var ret, err;
		
		if(..table.type(field) == "object"){
			var args = {}
			for(k,v in field){
				..table.push(args, tostring(k), tostring(v))
			}
			ret, err = this.command("HSET", key, ..table.unpack(args)); 
		}
		else {
			ret, err = this.command("HSET", key, field, value, ...); 
			
		}

		if(ret >= 0){
			return true, ret; 
		}
		return false, err;
	};
	hget = function(key, field){
		return this.command("HGET", key, field); 
	}; 
	hgetall = function(key){
		var res, err = this.command("HGETALL", key);
		if(res === false){
			return res, err; 
		}
		
		var ret = {};
		for(i=1;#res;2){
			var k = res[i];
			var v = res[i+1];
			ret[k] = v;
		}
		return ret;
	};
}
namespace redis{
    resp = {
        simpleStrings = "+";
        errors = "-";
        integers = ":";
        bulkStrings = "$";
        arrays = "*";
        CRLF = '\r\n';
    }
    
    respCharCode = {
        simpleStrings = 43;
        errors = 45;
        integers = 58;
        bulkStrings = 36;
        arrays = 42;
    } 	
}
// http://doc.redisfans.com/
// https://github.com/tporadowski/redis
// https://github.com/tporadowski/redis/releases
/**intellisense()
aaz.redis() = 创建 redis 客户端\n!aaz_redis.
aaz.redis = redis 客户端
end intellisense**/

/**intellisense(!aaz_redis)
set(.(key,value) = 将字符串值 value 关联到 key
ttl(.(key) = 以秒为单位,返回给定 key 的剩余生存时间 当 key 不存在时,返回 -2 , \n当 key 存在但没有设置剩余生存时间时,返回 -1
pttl(.(key) = 以毫秒为单位,返回给定 key 的剩余生存时间 当 key 不存在时,返回 -2 , \n当 key 存在但没有设置剩余生存时间时,返回 -1 
end intellisense**/


demo代码如下:

import console; 

import aaz.redis;

var redis = aaz.redis()
redis.connect() 

console.log( redis.setex("key1", "value", "2") )
console.log(redis.get("key1"))

console.pause(true);


2021-12-27   #3

区别是用 wsock.tcp.client 根据协议实现一次。

2021-12-27   #4

2021-12-28   #5

回复#5 @jacen :

感谢改进

2022-06-30   #6

找到一个 redis 7.0.2 的  x64 服务端


https://github.com/zkteco-home/redis-windows

2022-07-02   #7

回复#6 @terrorist :

登录后方可回帖

登 录
信息栏
公告:
个人博客
专注分享
可在分享中适当提问
谢绝纯提问
否则不再提醒一律
删帖
谢谢合作!



本站域名:HtmLayout.Cn
aardio可以快速开发上位机,本站主要记录了学习过程中遇到的问题和解决办法及aardio代码分享

这里主要专注于aardio学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.

Aardio 官方站:Aardio官方
Aardio最新功能:Aardio官方更新日志
本 站 主 站:Stm32cube中文网
Sciter中文在线文档Sciter在线学习文档
空间赞助:才仁机械
Loading...