精华内容
下载资源
问答
  • 生成业务逻辑相关的 Service/ServiceImpl 生成操作数据库的 Dao 接口与 Mapper.xml 映射文件 生成单元测试等 软件最大的特色就是操作 SQL 类的 Assist 查询帮助类(Assist 是特别定制的查询工具,使用该工具一切...
  • 开发者通过运行密码设置适用开发环境的业务逻辑,运行测试数据库以确认数据库功能符合开发目标。 1.2.3 演示数据库: 演示数据库是开发数据库的子集,只包含若干典型的产品规范和适用产品规范的所有试验标准的数据,...
  • 15.3.2 数据库逻辑结构设计 15.4 处理过程分析 15.4.1 添加资产设备处理过程分析 15.4.2 计提折旧处理过程分析 15.5 程序框架设计 15.6 封装数据库操作 15.6.1 导入ADO动态链接库 15.6.2 封装ADO对象 15.7 菜单设计 ...
  • 15.3.2 数据库逻辑结构设计 15.4 处理过程分析 15.4.1 添加资产设备处理过程分析 15.4.2 计提折旧处理过程分析 15.5 程序框架设计 15.6 封装数据库操作 15.6.1 导入ADO动态链接库 15.6.2 封装ADO对象 15.7 菜单设计 ...
  • 分布式数据库系统及其应用(第二版)

    千次下载 热门讨论 2009-04-16 17:44:43
    1·3·1 局部数据库管理系统的数据模型分类 1·3·2 分布式数据库控制系统的类型分类 1·4 分布式数据库系统的体系结构和组成成分 1·4·1 分布式数据库系统的体系结构 1·4·2 分布式数据库管理系统的组成成分...
  • 通配符 %U,它指示文件需要创建,格式将为expCASES_nn.dmp,其中nn 从 01 开始,然后需要向上增加 相关监控 -- 监控长事务 set linesize 120 column opname heading 'Operation' format a25 column target ...
  • 数据库课程设计(基于B/S)

    热门讨论 2008-12-28 15:28:06
    参考有关资料,选择自己了解的一项业务,运用课堂所学数据库系统与数据库设计知识,完成信息需求分析、数据库概念设计、逻辑设计、物理设计,实现完成该业务数据库应用系统,并运行、评价改进之,最后要写出课程...
  • 程序描述:本章实现了一个网上书店系统,采用面向对象的思想,系统的业务逻辑层包括图书类Book、购物车类Cart、会员类User、订单类Order以及订单详细信息类OrderDetail。 \db\db.sql 数据库实现SQL语句 \ ...
  • 业务逻辑: 首先我们先想一下,什么地方用的到图片上传,大家就会第一时间想到注册账号,发表动态等等,但是我们的文件上传只出现一个路径而不是一张图片,PHP存储问题,肯定不是当我选择之后就存储数据库,不是跟...

    tp5图片文件上传

    选择图片,显示图片,进行存储;
    html部分

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
    	<script src="/static/js/jquery.js" type="text/javascript" charset="utf-8"></script>
        <title>上传图片</title>
    </head>
        <body>
    	<h2>tp5图片上传</h2>
    		<form id="form">
    			<input type="file" id="image" name="image" onchange="picture(this);" />
    			<img class="img">
    		</form>
        </body>
    	<script type="text/javascript">
    		 function picture() {
    			var datas = new FormData($('#form')[0]);
    				console.log(datas);
    				$.ajax({
    					url:"/index/index/img",
    					type:'POST',
    					data:datas,
    					dataType:'json',
    					cache:false,
    					processData:false,
    					contentType:false,
    					success: function(data) {
    						console.log(data);
    						$('.img').attr("src",""+data+"");
    					},
    				});
    	}
        </script>
    </html>
    
    public function img()
    	{	
    		$file = request()->file('image');//获取图片
    		$info = $file->move(ROOT_PATH . 'public' . DS . 'uploads');//图片存储
    		if($info){
               $a= $info->getSaveName(); 
    		   $b='/uploads/'.$a;
    		   return $b;
    		}
    	}
    

    一个简单的上传图片的小功能,但是我是没有写数据存储。
    请各位大佬多多指教!!!!

    展开全文
  • 业务逻辑是,点击我的文件,会在展示界面展示出该用户所有文件 单机图标会显示选项下载,分享,删除,属性 单机空白处会显示选型,会显示选项:下载量排序/下载量排序/刷新/上传 其中上传操作也可以点击界面中的...

    我的文件列表

    • 业务逻辑是,点击我的文件,会在展示界面展示出该用户所有文件
    • 单机图标会显示选项下载,分享,删除,属性
    • 单机空白处会显示选型,会显示选项:按下载量排序/按下载量排序/刷新/上传
    • 其中上传操作也可以点击界面中的上传图标,然后会弹出窗口选择要上传的文件,上传过程是一个toolbar会显示进度在传输列表中

    在这里插入图片描述

    • 实质是两张表联查 file_info, user_file_list ,做了物理分页,根据指令按照pv字段做升序降序排列

    Mian

    • 读取配置文件 read_cfg();拿到数据库连接

    • while (FCGI_Accept() >= 0)等待连接

    • 业务主要分两种,一是只想知道用户有多少个文件,另一个是普通排序,按照pv升降序排序;均为post请求;为post请求时,由环境变量cmd拿到请求指令,由buf缓冲区拿到数据

    • cmd为count,获取用户文件个数if (strcmp(cmd, “count”) == 0) ,查表 get_user_files_count(user, ret); //获取用户文件个数

    • cmd为normal;pvacs;pvdesc;获取用户文件列表 get_user_filelist(cmd, user, start, count);

    • 需要注意的是,在fcgi程序中,直接fread是从标准输入读,就是从web服务器读;直接printf就是往标准输出,也是往web服务器(cgi程序利用I.O重定向技术)

        	int main()
        			{
        			    //count 获取用户文件个数
        			    //display 获取用户文件信息,展示到前端
        			    char cmd[20];
        			    char user[USER_NAME_LEN];
        			    char token[TOKEN_LEN];
        			
        		     //读取数据库配置信息
        		    read_cfg();
        		
        		    //阻塞等待用户连接
        		    while (FCGI_Accept() >= 0)
        		    {
        		
        		        // 获取URL地址 "?" 后面的内容
        		        char *query = getenv("QUERY_STRING");
        		
        		        //解析命令
        		        query_parse_key_value(query, "cmd", cmd, NULL);
        		        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cmd = %s\n", cmd);
        		
        		        char *contentLength = getenv("CONTENT_LENGTH");
        		        int len;
        		
        		        printf("Content-type: text/html\r\n\r\n");
        		
        		        if( contentLength == NULL )
        		        {
        		            len = 0;
        		        }
        		        else
        		        {
        		            len = atoi(contentLength); //字符串转整型
        		        }
        		
        		        if (len <= 0)
        		        {
        		            printf("No data from standard input.<p>\n");
        		            LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "len = 0, No data from standard input\n");
        		        }
        		        else
        		        {
        		            char buf[4*1024] = {0};
        		            int ret = 0;
        		            ret = fread(buf, 1, len, stdin); //从标准输入(web服务器)读取内容
        		            if(ret == 0)
        		            {
        		                LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "fread(buf, 1, len, stdin) err\n");
        		                continue;
        		            }
        		
        		            LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "buf = %s\n", buf);
        		
        		            if (strcmp(cmd, "count") == 0) //count 获取用户文件个数
        		            {
        		                get_count_json_info(buf, user, token); //通过json包获取用户名, token
        		
        		                //验证登陆token,成功返回0,失败-1
        		                ret = verify_token(user, token); //util_cgi.h
        		
        		                get_user_files_count(user, ret); //获取用户文件个数
        		
        		            }
        		            //获取用户文件信息 127.0.0.1:80/myfiles&cmd=normal
        		            //按下载量升序 127.0.0.1:80/myfiles?cmd=pvasc
        		            //按下载量降序127.0.0.1:80/myfiles?cmd=pvdesc
        		            else
        		            {
        		                int start; //文件起点
        		                int count; //文件个数
        		                get_fileslist_json_info(buf, user, token, &start, &count); //通过json包获取信息
        		                LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "user = %s, token = %s, start = %d, count = %d\n", user, token, start, count);
        		
        		                //验证登陆token,成功返回0,失败-1
        		                ret = verify_token(user, token); //util_cgi.h
        		                if(ret == 0)
        		                {
        		                     get_user_filelist(cmd, user, start, count); //获取用户文件列表
        		                }
        		                else
        		                {
        		                    char *out = return_status("111"); //token验证失败错误码
        		                    if(out != NULL)
        		                    {
        		                        printf(out); //给前端反馈错误码
        		                        free(out);
        		                    }
        		                }
        		
        		            }
        		
        		        }
        		
        		    }
        		
        		    return 0;
        		}
      

    读取配置信息

    • 读取到MySQL配置文件信息

        void read_cfg()
        {
            //读取mysql数据库配置信息
            get_cfg_value(CFG_PATH, "mysql", "user", mysql_user);
            get_cfg_value(CFG_PATH, "mysql", "password", mysql_pwd);
            get_cfg_value(CFG_PATH, "mysql", "database", mysql_db);
            LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "mysql:[user=%s,pwd=%s,database=%s]", mysql_user, mysql_pwd, mysql_db);
        
            //读取redis配置信息
            //get_cfg_value(CFG_PATH, "redis", "ip", redis_ip);
            //get_cfg_value(CFG_PATH, "redis", "port", redis_port);
            //LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "redis:[ip=%s,port=%s]\n", redis_ip, redis_port);
        }
      

    解析json登录token(cmd为count)

    • cmd为count时,此时的json包格式为

        {
        "token": "9e894efc0b2a898a82765d0a7f2c94cb",
         user:xxxx
        }
      
    • 此时,解析jason拿到token和username

        //解析的json包, 登陆token
        int get_count_json_info(char *buf, char *user, char *token)
        {
            int ret = 0;
        
        /*json数据如下
        {
            "token": "9e894efc0b2a898a82765d0a7f2c94cb",
            user:xxxx
        }
        */
      
        //解析json包
        //解析一个json字符串为cJSON对象
        cJSON * root = cJSON_Parse(buf);
        if(NULL == root)
        {
            LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_Parse err\n");
            ret = -1;
            goto END;
        }
      
        //返回指定字符串对应的json对象
        //用户
        cJSON *child1 = cJSON_GetObjectItem(root, "user");
        if(NULL == child1)
        {
            LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");
            ret = -1;
            goto END;
        }
      
        //LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child1->valuestring = %s\n", child1->valuestring);
        strcpy(user, child1->valuestring); //拷贝内容
      
        //登陆token
        cJSON *child2 = cJSON_GetObjectItem(root, "token");
        if(NULL == child2)
        {
            LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");
            ret = -1;
            goto END;
        }
      
        //LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child2->valuestring = %s\n", child2->valuestring);
        strcpy(token, child2->valuestring); //拷贝内容
      
        END:
            if(root != NULL)
            {
                cJSON_Delete(root);//删除json对象
                root = NULL;
            }
        
            return ret;
        }
      

    解析jason(cmd不为count)

    • 作用是为了拿到user,token,start,count,用来给普通/升/降序同时物理分页查询准备

        	//解析的json包
        	int get_fileslist_json_info(char *buf, char *user, char *token, int *p_start, int *p_count)
        	{
        	    int ret = 0;
        	
        	    /*json数据如下
        	    {
        	        "user": "yoyo"
        	        "token": xxxx
        	        "start": 0
        	        "count": 10
        	    }
        	    */
        	
        	    //解析json包
        	    //解析一个json字符串为cJSON对象
        	    cJSON * root = cJSON_Parse(buf);
        	    if(NULL == root)
        	    {
        	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_Parse err\n");
        	        ret = -1;
        	        goto END;
        	    }
        	
        	    //返回指定字符串对应的json对象
        	    //用户
        	    cJSON *child1 = cJSON_GetObjectItem(root, "user");
        	    if(NULL == child1)
        	    {
        	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");
        	        ret = -1;
        	        goto END;
        	    }
        	
        	    //LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child1->valuestring = %s\n", child1->valuestring);
        	    strcpy(user, child1->valuestring); //拷贝内容
        	
        	    //token
        	    cJSON *child2 = cJSON_GetObjectItem(root, "token");
        	    if(NULL == child2)
        	    {
        	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");
        	        ret = -1;
        	        goto END;
        	    }
        	
        	    strcpy(token, child2->valuestring); //拷贝内容
        	
        	    //文件起点
        	    cJSON *child3 = cJSON_GetObjectItem(root, "start");
        	    if(NULL == child3)
        	    {
        	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");
        	        ret = -1;
        	        goto END;
        	    }
        	
        	    *p_start = child3->valueint;
        	
        	    //文件请求个数
        	    cJSON *child4 = cJSON_GetObjectItem(root, "count");
        	    if(NULL == child4)
        	    {
        	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");
        	        ret = -1;
        	        goto END;
        	    }
        	
        	    *p_count = child4->valueint;
        	
        	END:
        	    if(root != NULL)
        	    {
        	        cJSON_Delete(root);//删除json对象
        	        root = NULL;
        	    }
        	
        	    return ret;
        	}
      

    获取用户文件个数

    • 数据库查询操作 sprintf(sql_cmd, “select count from user_file_count where user=”%s"", user);

    • 将结果封装进tmp int ret2 = process_result_one(conn, sql_cmd, tmp);

      		//获取用户文件个数
      		void get_user_files_count(char *user, int ret)
      		{
      		    char sql_cmd[SQL_MAX_LEN] = {0};
      		    MYSQL *conn = NULL;
      		    long line = 0;
      		
      		    //connect the database
      		    conn = msql_conn(mysql_user, mysql_pwd, mysql_db);
      		    if (conn == NULL)
      		    {
      		        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "msql_conn err\n");
      		        goto END;
      		    }
      		
      		    //设置数据库编码,主要处理中文编码问题
      		    mysql_query(conn, "set names utf8");
      		
      		    sprintf(sql_cmd, "select count from user_file_count where user=\"%s\"", user);
      		    char tmp[512] = {0};
      		    //返回值: 0成功并保存记录集,1没有记录集,2有记录集但是没有保存,-1失败
      		    int ret2 = process_result_one(conn, sql_cmd, tmp); //指向sql语句
      		    if(ret2 != 0)
      		    {
      		        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 操作失败\n", sql_cmd);
      		        goto END;
      		    }
      		
      		    line = atol(tmp); //字符串转长整形
      		
      		END:
      		    if(conn != NULL)
      		    {
      		        mysql_close(conn);
      		    }
      		
      		    LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "line = %ld\n", line);
      		
      		    //给前端反馈的信息
      		    return_login_status(line, ret);
      		}
      

      获取用户文件列表

    • get_user_filelist(char *cmd, char *user, int start, int count)需要参数cmd,user,start,count(这两个参数在前端设置好)

        - cmd为normal 
        普通查询只做了物理分页,==limit %d, %d", user, start, count==
         
        		    if(strcmp(cmd, "normal") == 0) //获取用户文件信息
        		    {
        		        //sql语句
        		        sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 limit %d, %d", user, start, count);
        		    }	
        	
        - cmd为pvasc
        升序查询按照pv排序同时做了物理分页,==order by pv asc limit %d, %d", user, start, count)==
        		
        			 else if(strcmp(cmd, "pvasc") == 0) //按下载量升序
        			    {
        			        //sql语句
        			        sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5  order by pv asc limit %d, %d", user, start, count);
        			    }
        			
        -  cmd为pvdesc
        降序查询按照pv排序同时做了物理分页,==order by pv desc limit %d, %d", user, start, count==
        
        			 else if(strcmp(cmd, "pvdesc") == 0) //按下载量降序
        			    {
        			        //sql语句
        			        sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 order by pv desc limit %d, %d", user, start, count);
        			    }
      
    • 进行查询 if (mysql_query(conn, sql_cmd) != 0)

    • 生成结果集 res_set = mysql_store_result(conn);/生成结果集/

    • 对结果集进行处理

      • 数据库的查询结果是一行行的,游标依次往下拿到每一个字段的值,封装进jason对象 cJSON_AddItemToArray(array, item);
      • 再封装进数组cJSON_AddItemToObject(root, “files”, array)代表所有文件的列表,
      • 再将该数组封装进root根对象转为字符串发送前端
        int get_user_filelist(char *cmd, char *user, int start, int count)
        {
            int ret = 0;
            char sql_cmd[SQL_MAX_LEN] = {0};
            MYSQL *conn = NULL;
            cJSON *root = NULL;
            cJSON *array =NULL;
            char *out = NULL;
            char *out2 = NULL;
            MYSQL_RES *res_set = NULL;
        
            //connect the database
            conn = msql_conn(mysql_user, mysql_pwd, mysql_db);
            if (conn == NULL)
            {
                LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "msql_conn err\n");
                ret = -1;
                goto END;
            }
        
            //设置数据库编码,主要处理中文编码问题
            mysql_query(conn, "set names utf8");
        
            //多表指定行范围查询
            if(strcmp(cmd, "normal") == 0) //获取用户文件信息
            {
                //sql语句
                sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 limit %d, %d", user, start, count);
            }
            else if(strcmp(cmd, "pvasc") == 0) //按下载量升序
            {
                //sql语句
                sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5  order by pv asc limit %d, %d", user, start, count);
            }
            else if(strcmp(cmd, "pvdesc") == 0) //按下载量降序
            {
                //sql语句
                sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 order by pv desc limit %d, %d", user, start, count);
            }
        
            LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 在操作\n", sql_cmd);
        
            if (mysql_query(conn, sql_cmd) != 0)
            {
                LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 操作失败:%s\n", sql_cmd, mysql_error(conn));
                ret = -1;
                goto END;
            }
        
            res_set = mysql_store_result(conn);/*生成结果集*/
            if (res_set == NULL)
            {
                LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "smysql_store_result error: %s!\n", mysql_error(conn));
                ret = -1;
                goto END;
            }
        
            ulong line = 0;
            //mysql_num_rows接受由mysql_store_result返回的结果结构集,并返回结构集中的行数
            line = mysql_num_rows(res_set);
            if (line == 0)//没有结果
            {
                LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "mysql_num_rows(res_set) failed:%s\n", mysql_error(conn));
                ret = -1;
                goto END;
            }
        
            MYSQL_ROW row;
        
            root = cJSON_CreateObject();
            array = cJSON_CreateArray();
            // mysql_fetch_row从使用mysql_store_result得到的结果结构中提取一行,并把它放到一个行结构中。
            // 当数据用完或发生错误时返回NULL.
            while ((row = mysql_fetch_row(res_set)) != NULL)
            {
                 //array[i]:
                cJSON* item = cJSON_CreateObject();
        
                //mysql_num_fields获取结果中列的个数
                /*for(i = 0; i < mysql_num_fields(res_set); i++)
                {
                    if(row[i] != NULL)
                    {
        
                    }
                }*/
        
                /*
                {
                "user": "yoyo",
                "md5": "e8ea6031b779ac26c319ddf949ad9d8d",
                "time": "2017-02-26 21:35:25",
                "filename": "test.mp4",
                "share_status": 0,
                "pv": 0,
                "url": "http://192.168.31.109:80/group1/M00/00/00/wKgfbViy2Z2AJ-FTAaM3As-g3Z0782.mp4",
                "size": 27473666,
                 "type": "mp4"
                }
        
                */
                //-- user	文件所属用户
                if(row[0] != NULL)
                {
                    cJSON_AddStringToObject(item, "user", row[0]);
                }
        
                //-- md5 文件md5
                if(row[1] != NULL)
                {
                    cJSON_AddStringToObject(item, "md5", row[1]);
                }
        
                //-- createtime 文件创建时间
                if(row[2] != NULL)
                {
                    cJSON_AddStringToObject(item, "time", row[2]);
                }
        
                //-- filename 文件名字
                if(row[3] != NULL)
                {
                    cJSON_AddStringToObject(item, "filename", row[3]);
                }
        
                //-- shared_status 共享状态, 0为没有共享, 1为共享
                if(row[4] != NULL)
                {
                    cJSON_AddNumberToObject(item, "share_status", atoi( row[4] ));
                }
        
                //-- pv 文件下载量,默认值为0,下载一次加1
                if(row[5] != NULL)
                {
                    cJSON_AddNumberToObject(item, "pv", atol( row[5] ));
                }
        
                //-- url 文件url
                if(row[6] != NULL)
                {
                    cJSON_AddStringToObject(item, "url", row[6]);
                }
        
                //-- size 文件大小, 以字节为单位
                if(row[7] != NULL)
                {
                    cJSON_AddNumberToObject(item, "size", atol( row[7] ));
                }
        
                //-- type 文件类型: png, zip, mp4……
                if(row[8] != NULL)
                {
                    cJSON_AddStringToObject(item, "type", row[8]);
                }
        
                cJSON_AddItemToArray(array, item);
            }
        
            cJSON_AddItemToObject(root, "files", array);
        
            out = cJSON_Print(root);
        
            LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s\n", out);
        
        END:
            if(ret == 0)
            {
                printf("%s", out); //给前端反馈信息
            }
            else
            {   //失败
                /*
                获取用户文件列表:
                    成功:文件列表json
                    失败:{"code": "015"}
                */
                out2 = NULL;
                out2 = return_status("015");
            }
            if(out2 != NULL)
            {
                printf(out2); //给前端反馈错误码
                free(out2);
            }
        
            if(res_set != NULL)
            {
                //完成所有对数据的操作后,调用mysql_free_result来善后处理
                mysql_free_result(res_set);
            }
        
            if(conn != NULL)
            {
                mysql_close(conn);
            }
        
            if(root != NULL)
            {
                cJSON_Delete(root);
            }
        
            if(out != NULL)
            {
                free(out);
            }
        
        
            return ret;
        }
      

    源码

    	/**
    	 * @file myfiles_cgi.c
    	 * @brief  用户列表展示CGI程序
    	 * @author Mike
    	 * @version 2.0
    	 * @date 2017年2月27日
    	 */
    	
    	#include "fcgi_config.h"
    	#include "fcgi_stdio.h"
    	#include <stdio.h>
    	#include <stdlib.h>
    	#include <string.h>
    	#include "make_log.h" //日志头文件
    	#include "util_cgi.h"
    	#include "deal_mysql.h"
    	#include "cfg.h"
    	#include "cJSON.h"
    	#include <sys/time.h>
    	
    	#define MYFILES_LOG_MODULE       "cgi"
    	#define MYFILES_LOG_PROC         "myfiles"
    	
    	//mysql 数据库配置信息 用户名, 密码, 数据库名称
    	static char mysql_user[128] = {0};
    	static char mysql_pwd[128] = {0};
    	static char mysql_db[128] = {0};
    	
    	//redis 服务器ip、端口
    	//static char redis_ip[30] = {0};
    	//static char redis_port[10] = {0};
    	
    	//读取配置信息
    	void read_cfg()
    	{
    	    //读取mysql数据库配置信息
    	    get_cfg_value(CFG_PATH, "mysql", "user", mysql_user);
    	    get_cfg_value(CFG_PATH, "mysql", "password", mysql_pwd);
    	    get_cfg_value(CFG_PATH, "mysql", "database", mysql_db);
    	    LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "mysql:[user=%s,pwd=%s,database=%s]", mysql_user, mysql_pwd, mysql_db);
    	
    	    //读取redis配置信息
    	    //get_cfg_value(CFG_PATH, "redis", "ip", redis_ip);
    	    //get_cfg_value(CFG_PATH, "redis", "port", redis_port);
    	    //LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "redis:[ip=%s,port=%s]\n", redis_ip, redis_port);
    	}
    	
    	
    	//解析的json包, 登陆token
    	int get_count_json_info(char *buf, char *user, char *token)
    	{
    	    int ret = 0;
    	
    	    /*json数据如下
    	    {
    	        "token": "9e894efc0b2a898a82765d0a7f2c94cb",
    	        user:xxxx
    	    }
    	    */
    	
    	    //解析json包
    	    //解析一个json字符串为cJSON对象
    	    cJSON * root = cJSON_Parse(buf);
    	    if(NULL == root)
    	    {
    	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_Parse err\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    //返回指定字符串对应的json对象
    	    //用户
    	    cJSON *child1 = cJSON_GetObjectItem(root, "user");
    	    if(NULL == child1)
    	    {
    	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    //LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child1->valuestring = %s\n", child1->valuestring);
    	    strcpy(user, child1->valuestring); //拷贝内容
    	
    	    //登陆token
    	    cJSON *child2 = cJSON_GetObjectItem(root, "token");
    	    if(NULL == child2)
    	    {
    	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    //LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child2->valuestring = %s\n", child2->valuestring);
    	    strcpy(token, child2->valuestring); //拷贝内容
    	
    	END:
    	    if(root != NULL)
    	    {
    	        cJSON_Delete(root);//删除json对象
    	        root = NULL;
    	    }
    	
    	    return ret;
    	}
    	
    	//返回前端情况
    	void return_login_status(long num, int token_flag)
    	{
    	
    	    char *out = NULL;
    	    char *token;
    	    char num_buf[128] = {0};
    	
    	    if(token_flag == 0)
    	    {
    	        token = "110"; //成功
    	    }
    	    else
    	    {
    	        token = "111"; //失败
    	    }
    	
    	    //数字
    	    sprintf(num_buf, "%ld", num);
    	
    	    cJSON *root = cJSON_CreateObject();  //创建json项目
    	    cJSON_AddStringToObject(root, "num", num_buf);// {"num":"1111"}
    	    cJSON_AddStringToObject(root, "code", token);// {"code":"110"}
    	    out = cJSON_Print(root);//cJSON to string(char *)
    	
    	    cJSON_Delete(root);
    	
    	    if(out != NULL)
    	    {
    	        printf(out); //给前端反馈信息
    	        free(out); //记得释放
    	    }
    	}
    	
    	//获取用户文件个数
    	void get_user_files_count(char *user, int ret)
    	{
    	    char sql_cmd[SQL_MAX_LEN] = {0};
    	    MYSQL *conn = NULL;
    	    long line = 0;
    	
    	    //connect the database
    	    conn = msql_conn(mysql_user, mysql_pwd, mysql_db);
    	    if (conn == NULL)
    	    {
    	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "msql_conn err\n");
    	        goto END;
    	    }
    	
    	    //设置数据库编码,主要处理中文编码问题
    	    mysql_query(conn, "set names utf8");
    	
    	    sprintf(sql_cmd, "select count from user_file_count where user=\"%s\"", user);
    	    char tmp[512] = {0};
    	    //返回值: 0成功并保存记录集,1没有记录集,2有记录集但是没有保存,-1失败
    	    int ret2 = process_result_one(conn, sql_cmd, tmp); //指向sql语句
    	    if(ret2 != 0)
    	    {
    	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 操作失败\n", sql_cmd);
    	        goto END;
    	    }
    	
    	    line = atol(tmp); //字符串转长整形
    	
    	END:
    	    if(conn != NULL)
    	    {
    	        mysql_close(conn);
    	    }
    	
    	    LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "line = %ld\n", line);
    	
    	    //给前端反馈的信息
    	    return_login_status(line, ret);
    	}
    	
    	//解析的json包
    	int get_fileslist_json_info(char *buf, char *user, char *token, int *p_start, int *p_count)
    	{
    	    int ret = 0;
    	
    	    /*json数据如下
    	    {
    	        "user": "yoyo"
    	        "token": xxxx
    	        "start": 0
    	        "count": 10
    	    }
    	    */
    	
    	    //解析json包
    	    //解析一个json字符串为cJSON对象
    	    cJSON * root = cJSON_Parse(buf);
    	    if(NULL == root)
    	    {
    	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_Parse err\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    //返回指定字符串对应的json对象
    	    //用户
    	    cJSON *child1 = cJSON_GetObjectItem(root, "user");
    	    if(NULL == child1)
    	    {
    	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    //LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child1->valuestring = %s\n", child1->valuestring);
    	    strcpy(user, child1->valuestring); //拷贝内容
    	
    	    //token
    	    cJSON *child2 = cJSON_GetObjectItem(root, "token");
    	    if(NULL == child2)
    	    {
    	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    strcpy(token, child2->valuestring); //拷贝内容
    	
    	    //文件起点
    	    cJSON *child3 = cJSON_GetObjectItem(root, "start");
    	    if(NULL == child3)
    	    {
    	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    *p_start = child3->valueint;
    	
    	    //文件请求个数
    	    cJSON *child4 = cJSON_GetObjectItem(root, "count");
    	    if(NULL == child4)
    	    {
    	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    *p_count = child4->valueint;
    	
    	END:
    	    if(root != NULL)
    	    {
    	        cJSON_Delete(root);//删除json对象
    	        root = NULL;
    	    }
    	
    	    return ret;
    	}
    	
    	//获取用户文件列表
    	//获取用户文件信息 127.0.0.1:80/myfiles&cmd=normal
    	//按下载量升序 127.0.0.1:80/myfiles?cmd=pvasc
    	//按下载量降序127.0.0.1:80/myfiles?cmd=pvdesc
    	int get_user_filelist(char *cmd, char *user, int start, int count)
    	{
    	    int ret = 0;
    	    char sql_cmd[SQL_MAX_LEN] = {0};
    	    MYSQL *conn = NULL;
    	    cJSON *root = NULL;
    	    cJSON *array =NULL;
    	    char *out = NULL;
    	    char *out2 = NULL;
    	    MYSQL_RES *res_set = NULL;
    	
    	    //connect the database
    	    conn = msql_conn(mysql_user, mysql_pwd, mysql_db);
    	    if (conn == NULL)
    	    {
    	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "msql_conn err\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    //设置数据库编码,主要处理中文编码问题
    	    mysql_query(conn, "set names utf8");
    	
    	    //多表指定行范围查询
    	    if(strcmp(cmd, "normal") == 0) //获取用户文件信息
    	    {
    	        //sql语句
    	        sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 limit %d, %d", user, start, count);
    	    }
    	    else if(strcmp(cmd, "pvasc") == 0) //按下载量升序
    	    {
    	        //sql语句
    	        sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5  order by pv asc limit %d, %d", user, start, count);
    	    }
    	    else if(strcmp(cmd, "pvdesc") == 0) //按下载量降序
    	    {
    	        //sql语句
    	        sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 order by pv desc limit %d, %d", user, start, count);
    	    }
    	
    	    LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 在操作\n", sql_cmd);
    	
    	    if (mysql_query(conn, sql_cmd) != 0)
    	    {
    	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 操作失败:%s\n", sql_cmd, mysql_error(conn));
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    res_set = mysql_store_result(conn);/*生成结果集*/
    	    if (res_set == NULL)
    	    {
    	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "smysql_store_result error: %s!\n", mysql_error(conn));
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    ulong line = 0;
    	    //mysql_num_rows接受由mysql_store_result返回的结果结构集,并返回结构集中的行数
    	    line = mysql_num_rows(res_set);
    	    if (line == 0)//没有结果
    	    {
    	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "mysql_num_rows(res_set) failed:%s\n", mysql_error(conn));
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    MYSQL_ROW row;
    	
    	    root = cJSON_CreateObject();
    	    array = cJSON_CreateArray();
    	    // mysql_fetch_row从使用mysql_store_result得到的结果结构中提取一行,并把它放到一个行结构中。
    	    // 当数据用完或发生错误时返回NULL.
    	    while ((row = mysql_fetch_row(res_set)) != NULL)
    	    {
    	         //array[i]:
    	        cJSON* item = cJSON_CreateObject();
    	
    	        //mysql_num_fields获取结果中列的个数
    	        /*for(i = 0; i < mysql_num_fields(res_set); i++)
    	        {
    	            if(row[i] != NULL)
    	            {
    	
    	            }
    	        }*/
    	
    	        /*
    	        {
    	        "user": "yoyo",
    	        "md5": "e8ea6031b779ac26c319ddf949ad9d8d",
    	        "time": "2017-02-26 21:35:25",
    	        "filename": "test.mp4",
    	        "share_status": 0,
    	        "pv": 0,
    	        "url": "http://192.168.31.109:80/group1/M00/00/00/wKgfbViy2Z2AJ-FTAaM3As-g3Z0782.mp4",
    	        "size": 27473666,
    	         "type": "mp4"
    	        }
    	
    	        */
    	        //-- user	文件所属用户
    	        if(row[0] != NULL)
    	        {
    	            cJSON_AddStringToObject(item, "user", row[0]);
    	        }
    	
    	        //-- md5 文件md5
    	        if(row[1] != NULL)
    	        {
    	            cJSON_AddStringToObject(item, "md5", row[1]);
    	        }
    	
    	        //-- createtime 文件创建时间
    	        if(row[2] != NULL)
    	        {
    	            cJSON_AddStringToObject(item, "time", row[2]);
    	        }
    	
    	        //-- filename 文件名字
    	        if(row[3] != NULL)
    	        {
    	            cJSON_AddStringToObject(item, "filename", row[3]);
    	        }
    	
    	        //-- shared_status 共享状态, 0为没有共享, 1为共享
    	        if(row[4] != NULL)
    	        {
    	            cJSON_AddNumberToObject(item, "share_status", atoi( row[4] ));
    	        }
    	
    	        //-- pv 文件下载量,默认值为0,下载一次加1
    	        if(row[5] != NULL)
    	        {
    	            cJSON_AddNumberToObject(item, "pv", atol( row[5] ));
    	        }
    	
    	        //-- url 文件url
    	        if(row[6] != NULL)
    	        {
    	            cJSON_AddStringToObject(item, "url", row[6]);
    	        }
    	
    	        //-- size 文件大小, 以字节为单位
    	        if(row[7] != NULL)
    	        {
    	            cJSON_AddNumberToObject(item, "size", atol( row[7] ));
    	        }
    	
    	        //-- type 文件类型: png, zip, mp4……
    	        if(row[8] != NULL)
    	        {
    	            cJSON_AddStringToObject(item, "type", row[8]);
    	        }
    	
    	        cJSON_AddItemToArray(array, item);
    	    }
    	
    	    cJSON_AddItemToObject(root, "files", array);
    	
    	    out = cJSON_Print(root);
    	
    	    LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s\n", out);
    	
    	END:
    	    if(ret == 0)
    	    {
    	        printf("%s", out); //给前端反馈信息
    	    }
    	    else
    	    {   //失败
    	        /*
    	        获取用户文件列表:
    	            成功:文件列表json
    	            失败:{"code": "015"}
    	        */
    	        out2 = NULL;
    	        out2 = return_status("015");
    	    }
    	    if(out2 != NULL)
    	    {
    	        printf(out2); //给前端反馈错误码
    	        free(out2);
    	    }
    	
    	    if(res_set != NULL)
    	    {
    	        //完成所有对数据的操作后,调用mysql_free_result来善后处理
    	        mysql_free_result(res_set);
    	    }
    	
    	    if(conn != NULL)
    	    {
    	        mysql_close(conn);
    	    }
    	
    	    if(root != NULL)
    	    {
    	        cJSON_Delete(root);
    	    }
    	
    	    if(out != NULL)
    	    {
    	        free(out);
    	    }
    	
    	
    	    return ret;
    	}
    	
    	int main()
    	{
    	    //count 获取用户文件个数
    	    //display 获取用户文件信息,展示到前端
    	    char cmd[20];
    	    char user[USER_NAME_LEN];
    	    char token[TOKEN_LEN];
    	
    	     //读取数据库配置信息
    	    read_cfg();
    	
    	    //阻塞等待用户连接
    	    while (FCGI_Accept() >= 0)
    	    {
    	
    	        // 获取URL地址 "?" 后面的内容
    	        char *query = getenv("QUERY_STRING");
    	
    	        //解析命令
    	        query_parse_key_value(query, "cmd", cmd, NULL);
    	        LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cmd = %s\n", cmd);
    	
    	        char *contentLength = getenv("CONTENT_LENGTH");
    	        int len;
    	
    	        printf("Content-type: text/html\r\n\r\n");
    	
    	        if( contentLength == NULL )
    	        {
    	            len = 0;
    	        }
    	        else
    	        {
    	            len = atoi(contentLength); //字符串转整型
    	        }
    	
    	        if (len <= 0)
    	        {
    	            printf("No data from standard input.<p>\n");
    	            LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "len = 0, No data from standard input\n");
    	        }
    	        else
    	        {
    	            char buf[4*1024] = {0};
    	            int ret = 0;
    	            ret = fread(buf, 1, len, stdin); //从标准输入(web服务器)读取内容
    	            if(ret == 0)
    	            {
    	                LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "fread(buf, 1, len, stdin) err\n");
    	                continue;
    	            }
    	
    	            LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "buf = %s\n", buf);
    	
    	            if (strcmp(cmd, "count") == 0) //count 获取用户文件个数
    	            {
    	                get_count_json_info(buf, user, token); //通过json包获取用户名, token
    	
    	                //验证登陆token,成功返回0,失败-1
    	                ret = verify_token(user, token); //util_cgi.h
    	
    	                get_user_files_count(user, ret); //获取用户文件个数
    	
    	            }
    	            //获取用户文件信息 127.0.0.1:80/myfiles&cmd=normal
    	            //按下载量升序 127.0.0.1:80/myfiles?cmd=pvasc
    	            //按下载量降序127.0.0.1:80/myfiles?cmd=pvdesc
    	            else
    	            {
    	                int start; //文件起点
    	                int count; //文件个数
    	                get_fileslist_json_info(buf, user, token, &start, &count); //通过json包获取信息
    	                LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "user = %s, token = %s, start = %d, count = %d\n", user, token, start, count);
    	
    	                //验证登陆token,成功返回0,失败-1
    	                ret = verify_token(user, token); //util_cgi.h
    	                if(ret == 0)
    	                {
    	                     get_user_filelist(cmd, user, start, count); //获取用户文件列表
    	                }
    	                else
    	                {
    	                    char *out = return_status("111"); //token验证失败错误码
    	                    if(out != NULL)
    	                    {
    	                        printf(out); //给前端反馈错误码
    	                        free(out);
    	                    }
    	                }
    	
    	            }
    	
    	        }
    	
    	    }
    	
    	    return 0;
    	}
    

    共享文件列表

    业务逻辑,点击QT界面的共享列表,会显示背当前用户共享的文件,且是普通排序

    • 点击图标会显示取消分享,属性
    • 点击空白处会选项显示排行榜

    共享文件列表主要涉及的是file_info和share_file_list两张表查询

    main

    • cmd为count,代表获取该用户共享出去的文件个数,只返回给前端共享了的文件个数

         if (strcmp(cmd, "count") == 0) //count 获取用户文件个数
                {
                    get_share_files_count(); //获取共享文件个数
                }
      
    • 解析jason包拿到拿到count,start

    • 如果cmd为normal,则就按照查询顺序显示共享文件列表

    • 如果cmd为pvdesc,则将查询结果按照pv字段降序排列显示共享文件列表

    • 如果cmd为pvasc,则将查询结果按照pv字段升序排列显示为共享文件列表

    获取共享文件个数

    • get_share_files_count(),当cmd为count,则只需要查询共享文件个数

    • 从user_file_count查询处用户的共享文件个数

    		void get_share_files_count()
    		{
    		    char sql_cmd[SQL_MAX_LEN] = {0};
    		    MYSQL *conn = NULL;
    		    long line = 0;
    		
    	    //connect the database
    	    conn = msql_conn(mysql_user, mysql_pwd, mysql_db);
    	    if (conn == NULL)
    	    {
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "msql_conn err\n");
    	        goto END;
    	    }
    	
    	    //设置数据库编码,主要处理中文编码问题
    	    mysql_query(conn, "set names utf8");
    	
    	    sprintf(sql_cmd, "select count from user_file_count where user=\"%s\"", "xxx_share_xxx_file_xxx_list_xxx_count_xxx");
    	    char tmp[512] = {0};
    	    int ret2 = process_result_one(conn, sql_cmd, tmp); //指向sql语句
    	    if(ret2 != 0)
    	    {
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败\n", sql_cmd);
    	        goto END;
    	    }
    	
    	    line = atol(tmp); //字符串转长整形
    	
    	END:
    	    if(conn != NULL)
    	    {
    	        mysql_close(conn);
    	    }
    	
    	    LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "line = %ld\n", line);
    	    printf("%ld", line); //给前端反馈的信息
    	}
    

    前端分页请求包

    • get_fileslist_json_info

    • 这个包是前端发送的post数据,封装的是物理分页的信息,然后再根据URL上的指令去做业务逻辑判断

    • 解析包拿到start,count

        //解析的json包
        		int get_fileslist_json_info(char *buf, int *p_start, int *p_count)
        		{
        		    int ret = 0;
        
            /*json数据如下
            {
                "start": 0
                "count": 10
            }
            */
        
            //解析json包
            //解析一个json字符串为cJSON对象
            cJSON * root = cJSON_Parse(buf);
            if(NULL == root)
            {
                LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_Parse err\n");
                ret = -1;
                goto END;
            }
        
            //文件起点
            cJSON *child2 = cJSON_GetObjectItem(root, "start");
            if(NULL == child2)
            {
                LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_GetObjectItem err\n");
                ret = -1;
                goto END;
            }
        
            *p_start = child2->valueint;
        
            //文件请求个数
            cJSON *child3 = cJSON_GetObjectItem(root, "count");
            if(NULL == child3)
            {
                LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_GetObjectItem err\n");
                ret = -1;
                goto END;
            }
        
            *p_count = child3->valueint;
        
        END:
            if(root != NULL)
            {
                cJSON_Delete(root);//删除json对象
                root = NULL;
            }
        
            return ret;
        }
      

    获得普通共享文件列表

    • get_share_filelist(int start, int count)

    • 查出share_file_list所有记录,同时根据md5查file_info表部分文件信息并进行物理分页

    • 从结果集中将记录进行一行行封装成对象;将封装好的对象加入数组;将数组加到跟对象root,将root转为字符串输出

        //获取共享文件列表
        //获取用户文件信息 127.0.0.1:80/sharefiles&cmd=normal
        int get_share_filelist(int start, int count)
        {
            int ret = 0;
            char sql_cmd[SQL_MAX_LEN] = {0};
            MYSQL *conn = NULL;
            cJSON *root = NULL;
            cJSON *array =NULL;
            char *out = NULL;
            char *out2 = NULL;
            MYSQL_RES *res_set = NULL;
        
            //connect the database
            conn = msql_conn(mysql_user, mysql_pwd, mysql_db);
            if (conn == NULL)
            {
                LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "msql_conn err\n");
                ret = -1;
                goto END;
            }
        
            //设置数据库编码,主要处理中文编码问题
            mysql_query(conn, "set names utf8");
        
        
            //sql语句
            sprintf(sql_cmd, "select share_file_list.*, file_info.url, file_info.size, file_info.type from file_info, share_file_list where file_info.md5 = share_file_list.md5 limit %d, %d", start, count);
        
            LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 在操作\n", sql_cmd);
        
            if (mysql_query(conn, sql_cmd) != 0)
            {
                LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败: %s\n", sql_cmd, mysql_error(conn));
                ret = -1;
                goto END;
            }
        
            res_set = mysql_store_result(conn);/*生成结果集*/
            if (res_set == NULL)
            {
                LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "smysql_store_result error!\n");
                ret = -1;
                goto END;
            }
        
            ulong line = 0;
            //mysql_num_rows接受由mysql_store_result返回的结果结构集,并返回结构集中的行数
            line = mysql_num_rows(res_set);
            if (line == 0)
            {
                LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "mysql_num_rows(res_set) failed\n");
                ret = -1;
                goto END;
            }
        
            MYSQL_ROW row;
        
            root = cJSON_CreateObject();
            array = cJSON_CreateArray();
            // mysql_fetch_row从使用mysql_store_result得到的结果结构中提取一行,并把它放到一个行结构中。
            // 当数据用完或发生错误时返回NULL.
            while ((row = mysql_fetch_row(res_set)) != NULL)
            {
                 //array[i]:
                cJSON* item = cJSON_CreateObject();
        
                //mysql_num_fields获取结果中列的个数
                /*for(i = 0; i < mysql_num_fields(res_set); i++)
                {
                    if(row[i] != NULL)
                    {
        
                    }
                }*/
        
                /*
                {
                "user": "yoyo",
                "md5": "e8ea6031b779ac26c319ddf949ad9d8d",
                "time": "2017-02-26 21:35:25",
                "filename": "test.mp4",
                "share_status": 1,
                "pv": 0,
                "url": "http://192.168.31.109:80/group1/M00/00/00/wKgfbViy2Z2AJ-FTAaM3As-g3Z0782.mp4",
                "size": 27473666,
                 "type": "mp4"
                }
        
                */
                //-- user	文件所属用户
                if(row[0] != NULL)
                {
                    cJSON_AddStringToObject(item, "user", row[0]);
                }
        
                //-- md5 文件md5
                if(row[1] != NULL)
                {
                    cJSON_AddStringToObject(item, "md5", row[1]);
                }
        
                //-- createtime 文件创建时间
                if(row[2] != NULL)
                {
                    cJSON_AddStringToObject(item, "time", row[2]);
                }
        
                //-- filename 文件名字
                if(row[3] != NULL)
                {
                    cJSON_AddStringToObject(item, "filename", row[3]);
                }
        
                //-- shared_status 共享状态, 0为没有共享, 1为共享
                cJSON_AddNumberToObject(item, "share_status", 1);
        
        
                //-- pv 文件下载量,默认值为0,下载一次加1
                if(row[4] != NULL)
                {
                    cJSON_AddNumberToObject(item, "pv", atol( row[4] ));
                }
        
                //-- url 文件url
                if(row[5] != NULL)
                {
                    cJSON_AddStringToObject(item, "url", row[5]);
                }
        
                //-- size 文件大小, 以字节为单位
                if(row[6] != NULL)
                {
                    cJSON_AddNumberToObject(item, "size", atol( row[6] ));
                }
        
                //-- type 文件类型: png, zip, mp4……
                if(row[7] != NULL)
                {
                    cJSON_AddStringToObject(item, "type", row[7]);
                }
        
                cJSON_AddItemToArray(array, item);
            }
        
            cJSON_AddItemToObject(root, "files", array);
        
            out = cJSON_Print(root);
        
            LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s\n", out);
        
        END:
            if(ret == 0)
            {
                printf("%s", out); //给前端反馈信息
            }
            else
            {   //失败
                out2 = NULL;
                out2 = return_status("015");
            }
            if(out2 != NULL)
            {
                printf(out2); //给前端反馈错误码
                free(out2);
            }
        
            if(res_set != NULL)
            {
                //完成所有对数据的操作后,调用mysql_free_result来善后处理
                mysql_free_result(res_set);
            }
        
            if(conn != NULL)
            {
                mysql_close(conn);
            }
        
            if(root != NULL)
            {
                cJSON_Delete(root);
            }
        
            if(out != NULL)
            {
                free(out);
            }
        
            return ret;
        }
      

    共享文件排行榜

    • 操作redis “FILE_NAME_HASH”和“FILE_PUBLIC_ZSET”两张表和MySQL“share_file_list”,完成redis和MySQL数据交互
    • int get_ranking_filelist(int start, int count)
    • 拿到mysql中共享文件的数量,拿到redis中的共享文件的数量进行比较
      • 不相等,更新redis数据,删除redis中所有数据( FILE_PUBLIC_ZSET,FILE_NAME_HASH) ;再将mysql中的数据导入到mysql:查出share_file_list中md5,filename和pv字段,游标提取结果集每一行(md5+filename组成fileid和pv字段作为score一起添加到zset;将组合的fileid作为fileld,filename作为value添加到hash表)
    • 将zset按照score降序排序,其中排序有分页参数start,end;
    • 将排序后的集合从FILE_NAME_HASH取出filename,从FILE_PUBLIC_ZSET取出pv字段封装成对象;再将数据封装成对象转字符串后发送给前端 printf("%s", out),会在QT界面点击排行榜时候显示

    源码

    	/**
    	 * @file sharefiles_cgi.c
    	 * @brief  共享文件列表展示CGI程序
    	 * @author Mike
    	 * @version 2.0
    	 * @date 2017年3月7日21:46:57
    	 */
    	
    	#include "fcgi_config.h"
    	#include "fcgi_stdio.h"
    	#include <stdio.h>
    	#include <stdlib.h>
    	#include <string.h>
    	#include "make_log.h" //日志头文件
    	#include "util_cgi.h"
    	#include "deal_mysql.h"
    	#include "redis_keys.h"
    	#include "redis_op.h"
    	#include "cfg.h"
    	#include "cJSON.h"
    	#include <sys/time.h>
    	
    	#define SHAREFILES_LOG_MODULE       "cgi"
    	#define SHAREFILES_LOG_PROC         "sharefiles"
    	
    	//mysql 数据库配置信息 用户名, 密码, 数据库名称
    	static char mysql_user[128] = {0};
    	static char mysql_pwd[128] = {0};
    	static char mysql_db[128] = {0};
    	
    	//redis 服务器ip、端口
    	static char redis_ip[30] = {0};
    	static char redis_port[10] = {0};
    	
    	//读取配置信息
    	void read_cfg()
    	{
    	    //读取mysql数据库配置信息
    	    get_cfg_value(CFG_PATH, "mysql", "user", mysql_user);
    	    get_cfg_value(CFG_PATH, "mysql", "password", mysql_pwd);
    	    get_cfg_value(CFG_PATH, "mysql", "database", mysql_db);
    	    LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "mysql:[user=%s,pwd=%s,database=%s]", mysql_user, mysql_pwd, mysql_db);
    	
    	    //读取redis配置信息
    	    get_cfg_value(CFG_PATH, "redis", "ip", redis_ip);
    	    get_cfg_value(CFG_PATH, "redis", "port", redis_port);
    	    LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "redis:[ip=%s,port=%s]\n", redis_ip, redis_port);
    	}
    	
    	//获取共享文件个数
    	void get_share_files_count()
    	{
    	    char sql_cmd[SQL_MAX_LEN] = {0};
    	    MYSQL *conn = NULL;
    	    long line = 0;
    	
    	    //connect the database
    	    conn = msql_conn(mysql_user, mysql_pwd, mysql_db);
    	    if (conn == NULL)
    	    {
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "msql_conn err\n");
    	        goto END;
    	    }
    	
    	    //设置数据库编码,主要处理中文编码问题
    	    mysql_query(conn, "set names utf8");
    	
    	    sprintf(sql_cmd, "select count from user_file_count where user=\"%s\"", "xxx_share_xxx_file_xxx_list_xxx_count_xxx");
    	    char tmp[512] = {0};
    	    int ret2 = process_result_one(conn, sql_cmd, tmp); //指向sql语句
    	    if(ret2 != 0)
    	    {
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败\n", sql_cmd);
    	        goto END;
    	    }
    	
    	    line = atol(tmp); //字符串转长整形
    	
    	END:
    	    if(conn != NULL)
    	    {
    	        mysql_close(conn);
    	    }
    	
    	    LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "line = %ld\n", line);
    	    printf("%ld", line); //给前端反馈的信息
    	}
    	
    	//解析的json包
    	int get_fileslist_json_info(char *buf, int *p_start, int *p_count)
    	{
    	    int ret = 0;
    	
    	    /*json数据如下
    	    {
    	        "start": 0
    	        "count": 10
    	    }
    	    */
    	
    	    //解析json包
    	    //解析一个json字符串为cJSON对象
    	    cJSON * root = cJSON_Parse(buf);
    	    if(NULL == root)
    	    {
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_Parse err\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    //文件起点
    	    cJSON *child2 = cJSON_GetObjectItem(root, "start");
    	    if(NULL == child2)
    	    {
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_GetObjectItem err\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    *p_start = child2->valueint;
    	
    	    //文件请求个数
    	    cJSON *child3 = cJSON_GetObjectItem(root, "count");
    	    if(NULL == child3)
    	    {
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_GetObjectItem err\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    *p_count = child3->valueint;
    	
    	END:
    	    if(root != NULL)
    	    {
    	        cJSON_Delete(root);//删除json对象
    	        root = NULL;
    	    }
    	
    	    return ret;
    	}
    	
    	//获取共享文件列表
    	//获取用户文件信息 127.0.0.1:80/sharefiles&cmd=normal
    	int get_share_filelist(int start, int count)
    	{
    	    int ret = 0;
    	    char sql_cmd[SQL_MAX_LEN] = {0};
    	    MYSQL *conn = NULL;
    	    cJSON *root = NULL;
    	    cJSON *array =NULL;
    	    char *out = NULL;
    	    char *out2 = NULL;
    	    MYSQL_RES *res_set = NULL;
    	
    	    //connect the database
    	    conn = msql_conn(mysql_user, mysql_pwd, mysql_db);
    	    if (conn == NULL)
    	    {
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "msql_conn err\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    //设置数据库编码,主要处理中文编码问题
    	    mysql_query(conn, "set names utf8");
    	
    	
    	    //sql语句
    	    sprintf(sql_cmd, "select share_file_list.*, file_info.url, file_info.size, file_info.type from file_info, share_file_list where file_info.md5 = share_file_list.md5 limit %d, %d", start, count);
    	
    	    LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 在操作\n", sql_cmd);
    	
    	    if (mysql_query(conn, sql_cmd) != 0)
    	    {
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败: %s\n", sql_cmd, mysql_error(conn));
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    res_set = mysql_store_result(conn);/*生成结果集*/
    	    if (res_set == NULL)
    	    {
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "smysql_store_result error!\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    ulong line = 0;
    	    //mysql_num_rows接受由mysql_store_result返回的结果结构集,并返回结构集中的行数
    	    line = mysql_num_rows(res_set);
    	    if (line == 0)
    	    {
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "mysql_num_rows(res_set) failed\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    MYSQL_ROW row;
    	
    	    root = cJSON_CreateObject();
    	    array = cJSON_CreateArray();
    	    // mysql_fetch_row从使用mysql_store_result得到的结果结构中提取一行,并把它放到一个行结构中。
    	    // 当数据用完或发生错误时返回NULL.
    	    while ((row = mysql_fetch_row(res_set)) != NULL)
    	    {
    	         //array[i]:
    	        cJSON* item = cJSON_CreateObject();
    	
    	        //mysql_num_fields获取结果中列的个数
    	        /*for(i = 0; i < mysql_num_fields(res_set); i++)
    	        {
    	            if(row[i] != NULL)
    	            {
    	
    	            }
    	        }*/
    	
    	        /*
    	        {
    	        "user": "yoyo",
    	        "md5": "e8ea6031b779ac26c319ddf949ad9d8d",
    	        "time": "2017-02-26 21:35:25",
    	        "filename": "test.mp4",
    	        "share_status": 1,
    	        "pv": 0,
    	        "url": "http://192.168.31.109:80/group1/M00/00/00/wKgfbViy2Z2AJ-FTAaM3As-g3Z0782.mp4",
    	        "size": 27473666,
    	         "type": "mp4"
    	        }
    	
    	        */
    	        //-- user	文件所属用户
    	        if(row[0] != NULL)
    	        {
    	            cJSON_AddStringToObject(item, "user", row[0]);
    	        }
    	
    	        //-- md5 文件md5
    	        if(row[1] != NULL)
    	        {
    	            cJSON_AddStringToObject(item, "md5", row[1]);
    	        }
    	
    	        //-- createtime 文件创建时间
    	        if(row[2] != NULL)
    	        {
    	            cJSON_AddStringToObject(item, "time", row[2]);
    	        }
    	
    	        //-- filename 文件名字
    	        if(row[3] != NULL)
    	        {
    	            cJSON_AddStringToObject(item, "filename", row[3]);
    	        }
    	
    	        //-- shared_status 共享状态, 0为没有共享, 1为共享
    	        cJSON_AddNumberToObject(item, "share_status", 1);
    	
    	
    	        //-- pv 文件下载量,默认值为0,下载一次加1
    	        if(row[4] != NULL)
    	        {
    	            cJSON_AddNumberToObject(item, "pv", atol( row[4] ));
    	        }
    	
    	        //-- url 文件url
    	        if(row[5] != NULL)
    	        {
    	            cJSON_AddStringToObject(item, "url", row[5]);
    	        }
    	
    	        //-- size 文件大小, 以字节为单位
    	        if(row[6] != NULL)
    	        {
    	            cJSON_AddNumberToObject(item, "size", atol( row[6] ));
    	        }
    	
    	        //-- type 文件类型: png, zip, mp4……
    	        if(row[7] != NULL)
    	        {
    	            cJSON_AddStringToObject(item, "type", row[7]);
    	        }
    	
    	        cJSON_AddItemToArray(array, item);
    	    }
    	
    	    cJSON_AddItemToObject(root, "files", array);
    	
    	    out = cJSON_Print(root);
    	
    	    LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s\n", out);
    	
    	END:
    	    if(ret == 0)
    	    {
    	        printf("%s", out); //给前端反馈信息
    	    }
    	    else
    	    {   //失败
    	        out2 = NULL;
    	        out2 = return_status("015");
    	    }
    	    if(out2 != NULL)
    	    {
    	        printf(out2); //给前端反馈错误码
    	        free(out2);
    	    }
    	
    	    if(res_set != NULL)
    	    {
    	        //完成所有对数据的操作后,调用mysql_free_result来善后处理
    	        mysql_free_result(res_set);
    	    }
    	
    	    if(conn != NULL)
    	    {
    	        mysql_close(conn);
    	    }
    	
    	    if(root != NULL)
    	    {
    	        cJSON_Delete(root);
    	    }
    	
    	    if(out != NULL)
    	    {
    	        free(out);
    	    }
    	
    	    return ret;
    	}
    	
    	//获取共享文件排行版
    	//按下载量降序127.0.0.1:80/sharefiles?cmd=pvdesc
    	int get_ranking_filelist(int start, int count)
    	{
    	    /*
    	    a) mysql共享文件数量和redis共享文件数量对比,判断是否相等
    	    b) 如果不相等,清空redis数据,从mysql中导入数据到redis (mysql和redis交互)
    	    c) 从redis读取数据,给前端反馈相应信息
    	    */
    	
    	    int ret = 0;
    	    char sql_cmd[SQL_MAX_LEN] = {0};
    	    MYSQL *conn = NULL;
    	    cJSON *root = NULL;
    	    RVALUES value = NULL;
    	    cJSON *array =NULL;
    	    char *out = NULL;
    	    char *out2 = NULL;
    	    char tmp[512] = {0};
    	    int ret2 = 0;
    	    MYSQL_RES *res_set = NULL;
    	    redisContext * redis_conn = NULL;
    	
    	    //连接redis数据库
    	    redis_conn = rop_connectdb_nopwd(redis_ip, redis_port);
    	    if (redis_conn == NULL)
    	    {
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "redis connected error");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    //connect the database
    	    conn = msql_conn(mysql_user, mysql_pwd, mysql_db);
    	    if (conn == NULL)
    	    {
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "msql_conn err\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    //设置数据库编码,主要处理中文编码问题
    	    mysql_query(conn, "set names utf8");
    	
    	    //===1、mysql共享文件数量
    	    sprintf(sql_cmd, "select count from user_file_count where user=\"%s\"", "xxx_share_xxx_file_xxx_list_xxx_count_xxx");
    	    ret2 = process_result_one(conn, sql_cmd, tmp); //指向sql语句
    	    if(ret2 != 0)
    	    {
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败\n", sql_cmd);
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    int sql_num = atoi(tmp); //字符串转长整形
    	
    	    //===2、redis共享文件数量
    	    int redis_num = rop_zset_zcard(redis_conn, FILE_PUBLIC_ZSET);
    	    if(redis_num == -1)
    	    {
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "rop_zset_zcard 操作失败\n");
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "sql_num = %d, redis_num = %d\n", sql_num, redis_num);
    	
    	    //===3、mysql共享文件数量和redis共享文件数量对比,判断是否相等
    	    if(redis_num != sql_num)
    	    {//===4、如果不相等,清空redis数据,重新从mysql中导入数据到redis (mysql和redis交互)
    	
    	        //a) 清空redis有序数据
    	        rop_del_key(redis_conn, FILE_PUBLIC_ZSET);
    	        rop_del_key(redis_conn, FILE_NAME_HASH);
    	
    	        //b) 从mysql中导入数据到redis
    	        //sql语句
    	        strcpy(sql_cmd, "select md5, filename, pv from share_file_list order by pv desc");
    	
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 在操作\n", sql_cmd);
    	
    	        if (mysql_query(conn, sql_cmd) != 0)
    	        {
    	            LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败: %s\n", sql_cmd, mysql_error(conn));
    	            ret = -1;
    	            goto END;
    	        }
    	
    	        res_set = mysql_store_result(conn);/*生成结果集*/
    	        if (res_set == NULL)
    	        {
    	            LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "smysql_store_result error!\n");
    	            ret = -1;
    	            goto END;
    	        }
    	
    	        ulong line = 0;
    	        //mysql_num_rows接受由mysql_store_result返回的结果结构集,并返回结构集中的行数
    	        line = mysql_num_rows(res_set);
    	        if (line == 0)
    	        {
    	            LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "mysql_num_rows(res_set) failed\n");
    	            ret = -1;
    	            goto END;
    	        }
    	
    	         MYSQL_ROW row;
    	        // mysql_fetch_row从使用mysql_store_result得到的结果结构中提取一行,并把它放到一个行结构中。
    	        // 当数据用完或发生错误时返回NULL.
    	        while ((row = mysql_fetch_row(res_set)) != NULL)
    	        {
    	            //md5, filename, pv
    	            if(row[0] == NULL || row[1] == NULL || row[2] == NULL)
    	            {
    	                LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "mysql_fetch_row(res_set)) failed\n");
    	                ret = -1;
    	                goto END;
    	            }
    	
    	            char fileid[1024] = {0};
    	            sprintf(fileid, "%s%s", row[0], row[1]); //文件标示,md5+文件名
    	
    	            //增加有序集合成员
    	            rop_zset_add(redis_conn, FILE_PUBLIC_ZSET, atoi(row[2]), fileid);
    	
    	            //增加hash记录
    	            rop_hash_set(redis_conn, FILE_NAME_HASH, fileid, row[1]);
    	        }
    	    }
    	
    	    //===5、从redis读取数据,给前端反馈相应信息
    	    //char value[count][1024];
    	    value  = (RVALUES)calloc(count, VALUES_ID_SIZE); //堆区请求空间
    	    if(value == NULL)
    	    {
    	        ret = -1;
    	        goto END;
    	    }
    	
    	    int n = 0;
    	    int end = start + count - 1;//加载资源的结束位置
    	    //降序获取有序集合的元素
    	    ret = rop_zset_zrevrange(redis_conn, FILE_PUBLIC_ZSET, start, end, value, &n);
    	    if(ret != 0)
    	    {
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "rop_zset_zrevrange 操作失败\n");
    	        goto END;
    	    }
    	
    	    root = cJSON_CreateObject();
    	    array = cJSON_CreateArray();
    	    //遍历元素个数
    	    for(int i = 0; i < n; ++i)
    	    {
    	        //array[i]:
    	        cJSON* item = cJSON_CreateObject();
    	
    	        /*
    	        {
    	            "filename": "test.mp4",
    	            "pv": 0
    	        }
    	        */
    	
    	        //-- filename 文件名字
    	        char filename[1024] = {0};
    	        ret = rop_hash_get(redis_conn, FILE_NAME_HASH, value[i], filename);
    	        if(ret != 0)
    	        {
    	            LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "rop_hash_get 操作失败\n");
    	            ret = -1;
    	            goto END;
    	        }
    	        cJSON_AddStringToObject(item, "filename", filename);
    	
    	
    	        //-- pv 文件下载量
    	        int score = rop_zset_get_score(redis_conn, FILE_PUBLIC_ZSET, value[i]);
    	        if(score == -1)
    	        {
    	            LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "rop_zset_get_score 操作失败\n");
    	            ret = -1;
    	            goto END;
    	        }
    	        cJSON_AddNumberToObject(item, "pv", score);
    	
    	
    	        cJSON_AddItemToArray(array, item);
    	
    	    }
    	
    	    cJSON_AddItemToObject(root, "files", array);
    	
    	    out = cJSON_Print(root);
    	
    	    LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s\n", out);
    	
    	END:
    	    if(ret == 0)
    	    {
    	        printf("%s", out); //给前端反馈信息
    	    }
    	    else
    	    {   //失败
    	        out2 = NULL;
    	        out2 = return_status("015");
    	    }
    	    if(out2 != NULL)
    	    {
    	        printf(out2); //给前端反馈错误码
    	        free(out2);
    	    }
    	
    	    if(res_set != NULL)
    	    {
    	        //完成所有对数据的操作后,调用mysql_free_result来善后处理
    	        mysql_free_result(res_set);
    	    }
    	
    	    if(redis_conn != NULL)
    	    {
    	        rop_disconnect(redis_conn);
    	    }
    	
    	    if(conn != NULL)
    	    {
    	        mysql_close(conn);
    	    }
    	
    	    if(value != NULL)
    	    {
    	        free(value);
    	    }
    	
    	    if(root != NULL)
    	    {
    	        cJSON_Delete(root);
    	    }
    	
    	    if(out != NULL)
    	    {
    	        free(out);
    	    }
    	
    	
    	    return ret;
    	}
    	
    	int main()
    	{
    	    char cmd[20];
    	
    	    //读取数据库配置信息
    	    read_cfg();
    	
    	    //阻塞等待用户连接
    	    while (FCGI_Accept() >= 0)
    	    {
    	
    	        // 获取URL地址 "?" 后面的内容
    	        char *query = getenv("QUERY_STRING");
    	
    	        //解析命令
    	        query_parse_key_value(query, "cmd", cmd, NULL);
    	        LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cmd = %s\n", cmd);
    	
    	        printf("Content-type: text/html\r\n\r\n");
    	
    	        if (strcmp(cmd, "count") == 0) //count 获取用户文件个数
    	        {
    	            get_share_files_count(); //获取共享文件个数
    	        }
    	        else
    	        {
    	            char *contentLength = getenv("CONTENT_LENGTH");
    	            int len;
    	
    	            if( contentLength == NULL )
    	            {
    	                len = 0;
    	            }
    	            else
    	            {
    	                len = atoi(contentLength); //字符串转整型
    	            }
    	
    	            if (len <= 0)
    	            {
    	                printf("No data from standard input.<p>\n");
    	                LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "len = 0, No data from standard input\n");
    	            }
    	            else
    	            {
    	                char buf[4*1024] = {0};
    	                int ret = 0;
    	                ret = fread(buf, 1, len, stdin); //从标准输入(web服务器)读取内容
    	                if(ret == 0)
    	                {
    	                    LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "fread(buf, 1, len, stdin) err\n");
    	                    continue;
    	                }
    	
    	                LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "buf = %s\n", buf);
    	
    	                //获取共享文件信息 127.0.0.1:80/sharefiles&cmd=normal
    	                //按下载量升序 127.0.0.1:80/sharefiles?cmd=pvasc
    	                //按下载量降序127.0.0.1:80/sharefiles?cmd=pvdesc
    	
    	                int start; //文件起点
    	                int count; //文件个数
    	                get_fileslist_json_info(buf, &start, &count); //通过json包获取信息
    	                LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "start = %d, count = %d\n", start, count);
    	                 if (strcmp(cmd, "normal") == 0)
    	                 {
    	                    get_share_filelist(start, count); //获取共享文件列表
    	                 }
    	                 else if(strcmp(cmd, "pvdesc") == 0)
    	                 {
    	                    get_ranking_filelist(start, count);//获取共享文件排行版
    	                 }
    	
    	
    	            }
    	        }
    	
    	    }
    	
    	    return 0;
    	}
    
    展开全文
  • 业务场景1: 后台要上传视频,图片到网站的首页或者附页,上传后,视频,图片存储到服务器或cdn,但是此时还要加确定按钮以实现该视频,图片路径数据库的插入操作. 页面展现: 点击操作按钮,触发input的click事件,再监听...

    业务场景1: 后台要上传视频,图片到网站的首页或者附页,上传后,视频,图片存储到服务器或cdn,但是此时还要加确定按钮以实现该视频,图片路径数据库的插入操作.

    页面展现: 点击操作按钮,触发input的click事件,再监听input的change事件,完成按钮到input的文件上传转换.

    代码部分: 

    <video src="" id="showvideo2" style="height: 300px;width: 400px"></video>
    <form id="uploadVideo2Form" enctype='multipart/form-data' style="display: none">
      <input id="video2Input" name="video2" type="file" class="form-control-file" style="display: none;">
    </form>
    
    
    <a id="uploadVideo2Btn" iconCls="icon-add" class="easyui-linkbutton"
       plain="true">上传关于中商视频</a>
    <div id="video2Div"></div>

    上方表示视频的标签,用来获取ajax回调的路径参数,用于预览视频.

    form中的input为视频传入input, 而触发它的是下面的a标签.

    (这么做是实现样式的需要,单纯的input是非常难看的)

      var thisVideo = null;
    
      $("#uploadVideo1Btn").click(function () {
        thisVideo = 1;
        $("#video1Input").click();
      });
      $("#video1Input").change(videoAjax);
    
      $("#uploadVideo2Btn").click(function () {
        thisVideo = 2;
        $("#video2Input").click();
      });
      $("#video2Input").change(videoAjax);

    因为包含两个视频,所以用变量thisVideo来那个是哪个视频的操作.(用于ajax传值与回调配置)

    function videoAjax() {
        var uploadFile = $("#video" + thisVideo + "Input")[0].files[0];
        console.log(uploadFile);
        var formData = new FormData();
        formData.append("uploadFile", uploadFile);
        // if ("undefined" != typeof(uploadFile) && uploadFile != null && uploadFile != "") {
        $.ajax({
          url: '/upload/video' + '/' + thisVideo + '/', 
          type: 'POST',
          data: formData,
          async: false,
          cache: false,
          contentType: false, //不设置内容类型
          processData: false, //不处理数据
          success: function (result) {
            // alert(data);
            if (result.success) {
              $.messager.alert('操作结果', '上传数据成功');
              $("#booten").linkbutton('enable');
              $('#uploadonlineinfo').dialog('close');
              var videoPath = null;
              for (var i in result.data) {
                videoPath = result.data[i];
              }
              $("#showvideo" + thisVideo + "").attr("src", videoPath);
              //设定新的按钮,确定,取消该视频
              $("#uploadVideo" + thisVideo + "Btn").hide();
              let confirmBtn = document.createElement("button");
              let btnText = document.createTextNode("确定使用该视频");
              confirmBtn.id = "confirmBtn";
              confirmBtn.appendChild(btnText);
              confirmBtn.setAttribute("onclick", "confirmVideo()");
    
              let cancelBtn = document.createElement("button");
              let btnText1 = document.createTextNode("取消");
              cancelBtn.id = "cancelBtn";
              cancelBtn.appendChild(btnText1);
              cancelBtn.setAttribute("onclick", "cancelInAjax(1)");
    
              $("#video" + thisVideo + "Div").append(confirmBtn);
              $("#video" + thisVideo + "Div").append(cancelBtn);
    
              // $('#dg').datagrid('reload');
            } else {
              $.messager.alert('操作结果', '上传数据失败');
              $('#uploadonlineinfo').dialog('close');
            }
          }
        });
      }

    上面的ajax即video上传的ajax代码,注意上传成功后,执行了一系列操作: 隐藏上传按钮,展示[确定,取消]按钮.

    [确定,取消]按钮对应两个方法调用:

    //确定使用该视频
      function confirmVideo() {
        alert("确定视频方法")
        //执行ajax将视频url及modelId传入数据库video表
        let nowVideoSrc = $("#showvideo" + thisVideo + "").attr("src");
        let nowVideoModelId = thisVideo;
        $.ajax({
          url: '/demand/addVideo',
          data: {"v_url": nowVideoSrc, "model_id": nowVideoModelId},
          dataType: 'json',
          type: 'post',
          success: function (result) {
            if (result.success) {
              $.messager.alert('操作结果', '操作成功');
              cancelInAjax();
            } else {
              $.messager.alert('操作结果', '操作失败');
              cancelInAjax();
            }
          }
        })
      }
    
      //取消视频 或 确定后返回原始按钮
      function cancelInAjax(value) {
          alert("取消");
        if (value == 1) {
          $("#confirmBtn").hide();
          $("#cancelBtn").hide();
          $("#showvideo" + thisVideo + "").attr("src", "");
          $("#uploadVideo" + thisVideo + "Btn").show();
        } else {
          $("#confirmBtn").hide();
          $("#cancelBtn").hide();
          $("#uploadVideo" + thisVideo + "Btn").show();
        }
      }

    至此,文件上传后,预览,并再确定后执行文件路径的数据库保存顺序确立.

     

    转载于:https://www.cnblogs.com/ukzq/p/10687402.html

    展开全文
  • 一般而言,视图函数中存在两种逻辑,业务逻辑和表现逻辑。业务逻辑诸如我们在登录页面时输入用户名和密码后,点击确定按钮时,在数据库验证该用户名和密码是否正确,表现逻辑就是返回的要显示的正确的html文件业务...
            一般而言,视图函数中存在两种逻辑,业务逻辑和表现逻辑。业务逻辑诸如我们在登录页面时输入用户名和密码后,点击确定按钮时,在数据库验证该用户名和密码是否正确. 表现逻辑就是返回正确的html文件在浏览器中进行显示。业务逻辑和表现逻辑混杂在一起很容易导致代码的难以理解和维护。模板的引入就是为了解决这一问题,flask使用Jinja2模板引擎,将表现逻辑封装,使得业务逻辑和表现逻辑分离。

           flask中所使用的模板文件全部在根目录的templates文件夹下,先看一下之前引入的一个最简单的flask程序示例,我们直接在视图函数中返回了字符串,这就是将业务逻辑和表现逻辑混合,会造成代码的可读性差和难以维护:

    from flask import Flask
     
    app=Flask(__name__)
    
    @app.route('/')
    def index():
        return 'hello world'
    
    @app.route('/user/<name>')
    def user(name):
        return 'hello %s'%name
     
    if __name__=='__main__':
        app.run()

            现在我们利用模板修改上面的代码,实现业务逻辑和表现逻辑的分离.首先在当前的目录下建立templates目录,分别在目录下建新建index.html和user.html两个文件.我们在视图函数,借助render_template方法返回html.

            将上述代码改写为:

    from flask import Flask
    
    from flask import render_template
     
    app=Flask(__name__)
     
    @app.route('/')
    
    def index():
    
         return render_template('index.html')
    
    @app.route('/user/<name>')
     def user(name):
    
        return render_template('user.html',name=name)
     if __name__=='__main__':
        app.run()



    index.html:

    <h1>Hello world</h1>

    user.html:

    <h1>hello {{name}} </h1>


            完成上述修改之后,修改前后在界面上的效果是一致的。





    Github位置:
    https://github.com/HymanLiuTS/flaskTs

    克隆本项目:
    git clone git@github.com:HymanLiuTS/flaskTs.git
    获取本文源代码:
    git checkout FL08
    展开全文
  • 根据“需提供服务”的精神,提供通过网络访问的服务Service,以构建高度可重用的,以业务逻辑为中心的业务与应用系统。符合SOA的应用系统以松耦合的方式,对外提供标准的服务调用接口。他是软件的自然进化。应用...
  • 自动排班系统源码

    2021-03-19 13:36:53
    <p><fontface>三层模式,包含一个自动排班的业务逻辑年份自动排班,值班员工轮流值班,周六,周日排两班;其余每天一班。 数据库脚本在app_data文件夹;三层核心在app_code文件夹。 新手可以看一看 data下位Sql...
  • 由于对数据库所做的全部改动就保存在日志文件中,如果因为包括介质失效在内的某种失效而导致数据库文件丢失的话,可以利用物理备份和归档日志完全恢复数据库,不会丢失任何数据。所有已经提交的事务都可以查到。 ·...
  • 异常测试性质分为应用层的业务逻辑异常测试、系统硬件/网络/文件/数据库/缓存/中间件异常测试,其中包含了许多的场景(单机、分布式),但所有的场景均和这两项有直接的关系。 业务逻辑异常测试体现在当上述的第...
  • 分布式应用异常测试

    2021-01-29 20:44:33
    异常测试性质分为应用层的业务逻辑异常测试、系统硬件/网络/文件/数据库/缓存/中间件异常测试,其中包含了许多的场景(单机、分布式),但所有的场景均和这两项有直接的关系。
  •  2、业务逻辑层(BLL):针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理。  3、数据访问层(DAL):该层所做事务直接操作数据库,针对数据的增添、删除、修改、更新、查找等。 [编辑本段]...
  • 基本系统:能对你的表进行CRUD,查询,分页功能,提供一个自定义按钮,你可以在里面写入业务逻辑的代码, 系统是供二次开发的。让程序员的主要精力集中在后期的业务逻辑开发上,而不是写那些重复的代码。大家知道CRUD...
  • (2)附加数据库文件到sqlserver2000,数据库的文件在DataBase目录下。 (2)启动MyEclipse,选择文件->导入->导入现有的工程到WorkPlace,把项目导入 (3)发布SuperMarket这个web项目到tomcat服务器,启动服务器输入...
  • php MVC设计框架

    2016-12-30 17:04:28
    MVC模式下,客户直接发送请求到控制器,控制器根据用户的请求的资源分发到相对应的模型来处理,模型完成了业务逻辑后,把要数据发送到视图,视图显示返回给客户。这就是web 或是说B/S架构的MVC工作流程。 控制器: ...
  • 资源统一管理,统一销毁,使您专心于业务逻辑处理。换一种ASP的开发方式!!!新特性(New Features)DEBUG支持,开启DEBUG模式后可查看错误的源行;类似nodejs的模块加载方式,同时提供更灵活的使用方式核心模块需...
  • php mvc模式

    千次阅读 2012-02-07 10:39:59
    MVC模式下,客户直接发送请求到控制器,控制器根据用户的请求的资源分发到相对应的模型来处理,模型完成了业务逻辑后,把要数据发送到视图,视图显示返回给客户。这就是web 或是说B/S架构的MVC工作流程。 控制器: ...
  • 服务器与http模块知识

    2019-08-05 09:37:37
    服务器: 通俗的讲,能够提供某种服务的机器(计算机)称为服务器 。 即网站服务器,主要提供文档(文本、图片、视频、音频)浏览... 服务类型: 文件服务器,数据库服务器,邮件服务器,Web服务器 操作系统: Lin...
  • 至于什么MVC结构,其实就是三个Model,Contraller,View单词的简称,,Model,主要任务就是把数据库或者其他文件系统的数据 照我们需要的方式读取出来。View,主要负责页面的,把数据以html的形式显示给用户。...
  • 至于什么MVC结构,其实就是三个Model,Contraller,View单词的简称,,Model,主要任务就是把数据库或者其他文件系统的数据 照我们需要的方式读取出来。View,主要负责页面的,把数据以html的形式显示给用户。...
  • 至于什么MVC结构,其实就是三个Model,Contraller,View单词的简称,,Model,主要任务就是把数据库或者其他文件系统的数据 照我们需要的方式读取出来。View,主要负责页面的,把数据以html的形式显示给用户。...
  • Ecshop实现多语言录入和展示

    千次阅读 2013-12-08 17:06:22
    实现原理:通过对数据来源(页面和数据库)的控制,在尽量不改动系统业务逻辑的前提下实现该功能。 实现步骤: 1、将需要多语言的数据表复制多分,并以语言做后后缀,如 goods_info_en_us(英文表); 2...

空空如也

空空如也

1 2 3 4 5 ... 15
收藏数 293
精华内容 117
关键字:

数据库文件按业务逻辑