发布 redis 扩展库

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

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 :

登录后方可回帖

登 录
信息栏
 私人小站

本站域名

ChengXu.XYZ

投诉联系:  popdes@126.com



快速上位机开发学习,本站主要记录了学习过程中遇到的问题和解决办法及上位机代码分享

这里主要专注于学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.
如果侵权,联系 Popdes@126.com

友情链接
Aardio官方
Aardio资源网


才仁机械


网站地图SiteMap

Loading...