1.一文秒懂cli、snmp、yang、netconf、restconf、openconfig
2.一次vue-cli4项目升级到vite的帝国直播源码经历
3.å ç§ç¼ç¨è¯è¨çç®åç解
4.环氯茚酸简介
5.å¦ä½ç¼è¯SQLite-How To Compile SQLite
6.数据库中间件-cetus源码介绍
一文秒懂cli、snmp、yang、netconf、restconf、openconfig
前言
随着网络技术的不断进步,CLI、SNMP、NETCONF、RESTCONF、OPENCONFIG等网络管理技术应运而生,以满足不同场景下的管理需求。本文将总结这些技术的特点与应用场景。
CLI
CLI(命令行界面)自网络诞生以来,就是网络管理的基础。它提供简单且功能完备的界面,易于上手。然而,随着设备数量的增加,CLI的管理效率逐渐降低,自动化需求日益迫切。
SNMP
SNMP(简单网络管理协议)简化了网络设备的监控与管理,通过C/S架构实现设备与管理系统的交互。SNMP提供了三个版本,适用于数据采集和设备监控。虽然简单易用,但存在数据交互效率低和缺乏事务支持等问题。
NETCONF
NETCONF(网络配置协议)与RESTCONF等技术基于XML和HTTP协议,为设备配置提供了更高效和灵活的接口。NETCONF支持XML数据格式传输,具备配置、订阅等功能,但相较于RESTCONF在数据交互效率上有所不足。
RESTCONF
RESTCONF是NETCONF与HTTP协议的结合,以JSON格式提供高效的数据交互接口,简化了Web应用访问设备的需求。RESTCONF在性能和开发效率上优于NETCONF,新年网页源码成为现代网络设备管理的优选方案。
OPENCONFIG
面对不同厂商设备之间的互操作性问题,OPENCONFIG提出了一套与厂商无关的模型驱动网络管理方案。它通过通用数据模型、流式数据遥测、管理协议和测试合规性,实现了网络配置与监控的标准化,促进了设备间的兼容性和互操作性。
gNMI
gNMI(gRPC网络管理接口)作为一套基于gRPC的标准化网络管理接口,简化了设备间的数据交互,提高了性能和效率。gNMI提供了一套标准化的API,为设备管理和监控提供了强大的支持。
总结
CLI、SNMP、NETCONF、RESTCONF、OPENCONFIG等技术各具特色,适用于不同场景下的网络管理需求。技术选型应根据实际场景和需求选择最合适的方案。每项技术的诞生和发展都为网络管理带来了便利,它们都是网络技术发展的重要里程碑。
一次vue-cli4项目升级到vite的经历
背景
使用vue-cli4的项目,业务写多了之后开发运行和打包都慢了很多,为了提升开发体验以及更新团队技术框架,需要升级到更高级的脚手架上,两种方案:一是升级到vue-cli5,二是升级到最新的vite。
其中第一种方案升级简单,经过实验,打包的速度不升反慢,这可能和项目中的有依赖以及业务代码有关。
第二种方案升级vite,经过可行性调查,升级到vite的成功率非常高,最后决定从vue-cli4升级到vite,这是一个高风险高回报的事情,因为尽管市面上已存在很多升级成功的案列,但是每个项目都不一样,我们的项目也很庞大,依赖很多,网泰源码并没有%升级成功的把握。而升级成功的回报也很显而易见,开发环境几乎秒运行,开发体验得到了显著提升。
升级前后对比||vue-cli4|vite||---|---|---||开发启动时间|ms|ms||生产打包时间|s|s||打包体积|.6MB|.6MB||运行期间同一代码改动编译时间|ms|瞬时|
生产环境打包时间可能和我们项目中用到了太多vite插件有关系,但开发环境的提升非常显著。
项目状况项目中用到的Vue2,VueCli版本:4.5.,版本更新时间为.5.8,vueCli4的最后版本为4.5.(.3.),依赖的webpack版本为^4.0.0
组件库使用vant,依赖Less预处理器,通过vue.config.js配置设置了less主题色,在webpack仅支持less-loader@5版本以及对应的less版本
业务css预处理器为stylus:"^0..5",对应stylus-loader:"^3.0.2"
进行了多页打包(MPA)
使用了workbox-webpack-plugin插件配置了PWA:WorkboxWebpackPlugin
配置了多个路径映射(alias别名)
指定了文件输出路径以及hash配置
生产环境下关闭productionSourceMap以及css的sourceMap提升打包速度
proxy开启多个代理
用到了.env文件中的环境变量
按照开发规范忽略部分文件后缀以及index.js
移除了preload脚本
期望结果可以使用vite进行开发和打包
仍保留webpack打包功能(因为项目太大,不能保证升级到vite后会不会有问题,所以仍希望webpack原本功能正常运行)
准备工作升级Node版本,vite只支持node及以上,建议升级到v以上。
安装pnpm工具,pnpm作为更好的npm依赖管理工具,是目前npm和yarn的最好替代品,且有些依赖包使用npm安装时会有异常,使用pnpm安装可解决:pnpm
小项目尝试一键转换升级:wp2vite、webpack-to-vite,这两个工具都提供了一键将webpack项目转成vite的能力,但对于大中型项目,并不可靠。
开始行动1.安装必要依赖pnpm?add?vite-plugin-env-compatible?vite-plugin-html?vite?vite-plugin-vue2?--devvite-plugin-vue2是处理vue2版本代码的插件,如果项目中是vue3,安装的依赖有所不同,请参考webpack-to-vite
2.复制html到根目录,并修改 注意是复制,并只改动复制后的html,这样才不会破坏原有webpack功能。修改复制后的html,增加对应的js文件引用,注意type属性不能少!
<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>多页打包(MPA),其他页面的html同样操作,不同html引入对应的spark 看 源码js即可。
3.新增vite.config.js文件,开始迁移最重要的配置部分空配置如下:
import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ })4.修改环境变量环境变量主要面临两个问题:
要兼容webpack和vite的环境变量用法
解决方法:使用vite插件vite-plugin-env-compatible,让vite中可以使用webpack中读取环境变量的方式,再配合envPrefix配置,让vite可以读取到VUE_APP_开头的环境变量:
?pnpm?add?vite-plugin-env-compatible?-D?import?{ ?defineConfig?}?from?'vite'?import?envCompatible?from?'vite-plugin-env-compatible'?export?default?defineConfig({ plugins:?[?envCompatible()],envPrefix:?['VUE_APP_']?//?很重要?})?//?mian.js测试?console.log(process.env.VUE_APP_UNION_STATS)?console.log(import.meta.env.VUE_APP_UNION_STATS)两个打印都得到了正确的结果,注意:vite中默认只能读取到VITE_开头的环境变量,如果不配置envPrefix,则会导致第二个打印为undefind。
vite.config.js中不能读取到环境变量
vite.config.js是无法直接通过import.meta.env和process.env获取环境变量的,我们需要通过vite的loadEnv获取。
我们需要将vite.config.js的导出对象改为函数:
?import?{ ?defineConfig,loadEnv?}?from?'vite'?export?default?({ ?mode?})?=>?{ ?const?isPro?=?mode?===?'production'?//?我们可以通过mode直接判断当前是不是生产环境,注意mode可以在运行指令中指定:`vite?build?--mode?master`,如果没有指定,那默认打包就是production?function?getEnv(key)?{ ?//?定义获取环境变量的方法?return?loadEnv(mode,?process.cwd(),'')[key]?//?第三个参数非常重要,下面有详解?}?return?defineConfig({ ?base:?getEnv('VUE_APP_PUBLICPATH'),?//?读取环境变量?//?...忽略其他代码?})?})loadEnv有三个参数,前两个参数基本固定不变,而第三个参数默认情况下是不需要传的,只有在配置了envPrefix项,读取非VITE_开头的变量时才需要,在loadEnv源码中我们可以看到,第三个参数是prefixes:string|string[]='VITE_',也就是环境变量的前缀,默认是VITE_。
如果你的项目和我一样,读取了VUE_APP_PUBLICPATH这样非VITE_开头环境变量,就在loadEnv的第三个参数传递空字符串即可,这样就能读取到所有的环境变量了。
5.兼容commonjs代码项目中有用到commonjs规范的依赖,比如letmd5=require('js-md5').create(),webpack是基于node开发的,支持require语法,在打包的时候webpack也会正确处理这部分代码,但在vite中不会,所以需要将这部分代码改成importmd5from'js-md5'
项目开发环境下,一些node_modules中的包也会存在commonjs的代码,我们可以通过vite的插件?vite-plugin-commonjs来实现这部分代码的转化,保证开发环境的正常运行。
pnpm?add?@originjs/vite-plugin-commonjs?--dev//?vite.config.js?忽略其他代码import?{ ?viteCommonjs?}?from?'@originjs/vite-plugin-commonjs'export?default?({ ?mode?})?=>?{ return?defineConfig({ plugins:?[//?...viteCommonjs()?//?兼容vite中的cjs导入语法]})})6.解决css预处理的问题vite内置了对主流css预处理器的支持(sass/less/stylus),项目使用预处理器时,只需要安装对应预处理依赖即可:
#?.scss?and?.sasspnpm?add?sass?-D#?.lesspnpm?add?stylus?-D#?.styl?and?.styluspnpm?add?stylus?-D比较巧的是,我们项目中用到的蜘蛛采集源码Stylus的@import别名的语法和vite冲突,@import'~@/public/stylus/mixins'这样的代码是会报错,一开始我找到了插件,可以帮助我们解决这个问题:vite-plugin-stylus-alias,但是都后面打包的时候发现这个插件有副作用,后面采取了其他方法解决。
<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>0<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>1使用这个插件会导致无法生成sourcemap文件,在打包的时候可以看到警告:Sourcemapislikelytobeincorrect:aplugin(vite-plugin-stylus-alias)wasusedtotransformfiles,butdidn'tgenerateasourcemapforthetransformation.Consulttheplugindocumentationforhelp,鉴于插件作者已经很久没有更新,建议能改成相对路径还是直接改,如果引用地方较多,可以定义文件为全局styl文件最新解决方案:一般出现这个报错是因为插件使用了vite的transformapi转换代码,但是return值缺失导致,解决方法:复制插件代码到项目中,在插件transform函数return的结果中,返回map:null,然后再vite.config.js中引用项目中修改后的插件,即可完美解决,如下:文末解决bug有细说
<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>2定义stylus全局文件
<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>3这里需要注意,官方文档中css-preprocessoroptions写的是使用文件名拓展名作为key,stylus的文件拓展名是styl,但是我使用了stylus作为key并不会有问题,相反使用styl作为key则不生效了,后续这个地方可以留意一下。
在vite源码中,stylus和styl都进行了判断,理论上都可以使用,但目前测试的结果就是styl作为key不生效,可能源码中其他地方还能找到原因。
7.组件库按需导入和定制主题我们项目中用到的组件库是Vant2,该组件库依赖Less,以及通过配置文件来定制组件的主题,在配置中我们需要进行修改:
vue-cli中的主题配置部分如下:
<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>4vite中主题配置部分如下:
<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>5按需导入项目中按需导入vant组件库,组件可以成功导入,但是组件的样式缺失了,这是因为在webpack中,babel-plugin-import插件帮我们实现了组件的样式导入,在vite中使用?vite-plugin-style-import插件帮我们实现这个功能,不仅vant组件库,其他诸如element、antv等组件库也可以使用这个插件进行按需导入:
<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>6<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>.修改alias别名配置,以及忽略文件后缀vite配置别名的方法和vue-cli有所不同,且没有默认的别名,都需要通过配置实现,且vite默认不能忽略文件后缀导入,我们也需要通过修改配置来实现:
<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>8需要注意extensions配置的顺序,从左到右进行匹配,如果存在同名但类型不同的文件,很可能得到期望外的结果,比如同目录下存在index.js和index.vue,按上面的顺序,import'./index?会优先匹配到index.js文件。这种情况建议补全后缀进行导入。
9.配置前端跨域vite配置跨域和webpack也有出入,需要修改配置
<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>9以上就是几种常见的跨域配置方式,webpack中的devServer改为了server,webpack的proxy中的pathRewrite改成了rewrite,并且类型成为了函数,在函数中返回请求的路径即可。
.多页打包以及打包的其他配置vite在build.rollupOptions配置多页打包,参考rollupOptions,其他配置参考文档
import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ }).配置运行路径base是指项目运行在服务器的哪个路径下,一般通过从环境变量中动态获取。
import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ }).配置EsLintvite中使用vite-plugin-eslint插件实现eslint的检查功能,安装过程中发现vite-plugin-eslint@1.4.0会报错,安装1.3.0版本即可。
import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ })2import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ }).使用插件@vitejs/plugin-legacy兼容低版本浏览器plugin-legacy文档
import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ }).配置运行指令import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ })5可以在指令中声明mode环境,这个mode在vite.config.js中可以得到,具体可以参考前面4.修改环境变量
保存运行指令npmrunserve开发环境已经可以跑起来了,但是vite的特性是你用到的页面才会进行打包,其他页面没有进行访问,是不会打包的,所以需要进行打包才能知道其他地方改造会不会有问题,打包如果有报错,再解决报错即可。
.解决报错globalisnotdefined
这个错误是在node_modules/buffer/index.js?v=ea7文件中抛出的,我查看了yarn.lock文件,依赖路径为多个vue-cli插件>webpack@4.0.0>node-libs-browser?>buffer
这个是依赖的问题,第一删除node_modules重新安装依赖。第二更换npm工具为pnpm重装依赖,如果仍不行,建议不建议webpack,删除掉webpack相关依赖。
网上还有一种做法是:在window对象上挂载global对象,可作为备选方案。
import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ })6@import'~@vant/icons/src/encode-woff2.less';报错
这个错误是vant组件库中的icon组件抛出的,vite默认不能使用别名,我们在前面配置了别名,但是配置的是~@指向项目中的src目录,这样vant组件库的这个文件引用就找不到了。
issuesvant
解决方法:针对vant的这个文件,做一个别名,放到第一位,优先进行匹配:
import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ })7运行vitebuild,css产生了一些警告。
警告分为两种,一是css中的属性拼写错误,诸如:color写成了colo,background写成了backgrounc,属于语法错误,根据警告提示搜索对应样式进行修改即可。
二是一些语法正确,但还不清楚为什么压缩时提示了警告:比如stylus修改scoped样式用的>>>语法,以及background?rgba(0,0,0,0.5)提示Unexpected"rgba("。
Thepackagemayhaveincorrectmain/module/exportsspecifiedinitspackage.json
这个错误是通过npminstall后运行vite指令报错的,用yarn安装一直很正常,原因是node_modules的某个包的package.json定义的main入口路径错了,所以找不到模块导入。
解决方法:针对这个模块,定义别名,指向正确的入口:
import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ })8打包后导入函数定义别名后,调用函数报错
import*asminByfrom'lodash.minby'代码报错了,而且只有在生产环境下才产生。
解决方法:暂时去掉别名,这应该和lodash的导出方式modules.export在vite中转化成ES语法的过程有关系。
importminByfrom'lodash.minby'
requireisnotdefine,通过require导入资源报错
前面在步骤5已经用了插件vite-plugin-commonjs转化common.js的代码了,require理应不会报错。
但是require导入资源算是webpack的功能,和js代码不一样,所以导入资源的代码都要进行修改:
require('./images/logo.png')改成importlogofrom'./images/logo.png'
这样的修改可以兼容webpack和vite,这是在现有项目中,改动的地方会达到上百处,非常麻烦。
å ç§ç¼ç¨è¯è¨çç®åç解
ä¸é¢å åå«ç®ä»ä¸ã.Net.Netæ¡æ¶æ¯Windowsç ååºæ¥çè·¨è¯è¨è§£å³æ¹æ¡ãå®çæ ¸å¿æ¯CLRï¼å ¬å ±è¯è¨è¿è¡åºï¼ï¼è¿æ¯å¾®è½¯åå¸çCLIï¼å ¬å ±è¯è¨åºç¡ç»æï¼è§èçä¸ä¸ªå®ç°ãCLIå为两é¨åï¼ä¸ä¸ªæ¯CILï¼å ¬å ±ä¸é´è¯è¨ï¼ï¼å¦ä¸ä¸ªæ¯CTSï¼å ¬å ±ç±»åç³»ç»ï¼ãå¯ä»¥æ³è±¡ï¼åºäºå ¬å ±ç±»åç³»ç»ï¼.netå°±å¯ä»¥æå ¶ä¸çåç§è¯è¨ä¸çæ°æ®ç±»åç¿»è¯ä¸ºå ¬å ±æ°æ®ç±»åï¼åå°å ¶ç¿»è¯ä¸ºå ¬å ±ä¸é´è¯è¨ï¼å°±å¯ä»¥å®ç°è·¨è¯è¨çäºéãæ¬æ¥ç¨åºå°±åºæ¬çäºæ°æ®+æµç¨é»è¾ï¼ä¸¤é¨åé½ä½¿ç¨äºå ¬å ±è§èè¿è¡çº¦æåï¼å®ç°äºéæ§å°±æå¯è½äºãè¿ä¹æ¯å¥çº¦å¼ç¼ç¨çä¸ç§ææ³ä½ç°å§ã.Netæ¡æ¶ä¸çè¯è¨ï¼å¨çææ¶ï¼ç¼è¯å¨å°å ¶ç¿»è¯ä¸ºä¸é´è¯è¨ï¼å¨æ§è¡åå³æ¶ç¼è¯ï¼å³JITæ¹å¼ï¼è°å ¥å å并è¿è¡ãæ¤å¤ï¼.Netçè¿è¡æ¶ç¯å¢ä¸Javaèææºè¿æ¯æ¯è¾ç¸åçï¼é½æ¯åºäºå çå å管çæºå¶ï¼æ管模å¼ä¸æ²¡æCé£æ ¼æéï¼éæ管代ç å¯ä»¥ä½¿ç¨ï¼ï¼é½æç±»åç³»ç»ï¼.Net称为å æ°æ®ï¼Javaå°±æ¯ä¸ç³»åçClassç±»åç对象å®ä¾ãè¿æ ·çç»æä½¿å ¶å¾æ¹ä¾¿è½å¤æ¯æåå°è¿æ ·çæºå¶ï¼ä½¿ç¨åºå¯ç¼ç¨çµæ´»æ§æå¾å¤§æé«ãJavaJavaæ¯ç®åææµè¡çè¯è¨ä¹ä¸ï¼å®çä¼ç¹å°±æ¯è·¨å¹³å°å移å¨æ§ãå®æ¯åºäºJavaèææºçæ¶æï¼Javaæºç¨åºè¢«ç¿»è¯ä¸º.classæ件çåèç ï¼Javaèææºæ¥åè¿äºåèç æµï¼è§£æ并çæç¸åºçç±»åæ°æ®å¹¶ä»mainæ¹æ³å¼å§è¿è¡ãè³äºæºä»£ç çè¿æ¥å è½½çæä½å®å ¨äº¤ç»èææºå»å¤çãJavaå.Netå¾åï¼æè¯è¨æ¥è¯´ï¼JavaåC#çè¯æ³ç»æå°±å¾åï¼èC#åæ¯.Netä¸æææ¹ä¾¿çè¯è¨ãåªä¸è¿.Net主è¦è¿æ¯åºäºWindowsçå®ç°ï¼èJavaèææºæå¤ä¸ªæä½ç³»ç»çå®ç°ãåè å ³æ³¨ç¹å¨è·¨è¯è¨ï¼åè å ³æ³¨ç¹å¨äºè·¨å¹³å°ãPythonPythonæ¯ä¸ç§ç¸å½å¹´è½»çè¯è¨ï¼å®åå±çå¾å¿«ï¼ç¨æ·éä¸æå¢å¤ãè¿ç§è¯è¨ç»æçå°è±¡å°±æ¯å¯¹ç¼ç é£æ ¼è¦æ±å¾é«ï¼åæ¬å°±æ¯é 缩è¿æ¥çº¦æç¨åºåçï¼ãè¿æ ·åå¤å°±æ¯å代ç å°±å¾æ ¼å¤å°å¿ï¼å¥½å¤å°±æ¯ååºæ¥ç代ç æ®éé£æ ¼è¾å¥½ï¼æäºç解ãæ强大ç代ç åºå¯ä»¥ä½¿ç¨ï¼æ¯æå¾å¤ä¸å±è¯è¨çç¹æ§ãç®åä¼¼ä¹ä½ä¸ºèæ¬è¯è¨ä½¿ç¨çè¾å¤ï¼ç»å¸¸çæ人ç¨å®åPerlæ¯ï¼ï¼ä½æ¬èº«æ¯ä¸ç§éç¨åçè¯è¨ï¼ä¹å¯ä»¥æ¯æå¾å½¢å¼åãå®çè¿è¡åçä¸Java大è´ç¸åï¼ä¹æèææºï¼æ§è¡æ¶å°æºç ç¿»è¯ä¸ºä¸é´è¯è¨ï¼åå è½½å°èææºä¸å»æ§è¡ãPythonå¯ä»¥æ¯ææºç ç´æ¥è¿è¡ï¼ä½å ¶èåä»ç¶æ¯å æ§è¡äºå°æºç 转æ¢å°ä¸é´ä»£ç çè¿ç¨ï¼ç¶åå解éæ§è¡ãå½ç¶ä¸ºäºæçï¼ä¹å¯ä»¥å°æºç äºå ç¿»è¯ä¸º.pycåèç æ件ï¼å解éæ§è¡ï¼è¿å°±åJavaæ¯è¾åäºï¼ãåJavaç¸æ¯ï¼æ认为Pythonçä¼å¿å¨äºå®çæç¨æ§ï¼ä»£ç ååºæ¥å¾ç®æ´ï¼æ¯æé«ç«¯ç¹æ§ï¼å¨æç±»åï¼ä½ä¸ºä¸å±è¯è¨æ¯ä¸ªå¾ä¸éçéæ©ãç®åç解就æ¯ç®åç解ï¼ç°å¨ä¸»è¦å ³æ³¨ç¹å°±å¨è¿éã以åææºä¼çè¯ï¼åæ·±å ¥ä¸äºç»èå§ã
环氯茚酸简介
环氯茚酸是一种具有药理活性的药物,其主要功效在于解热、镇痛和抗炎,其作用机制是通过抑制前列腺素的合成。它适用于多种关节炎症的治疗,包括变形性关节炎、肩关节炎和颈肩腕综合征,以及腰痛的缓解。
对于使用方法,一般推荐成人每日服用至毫克,最好将其分为2到3次,且需在饭后服用以提高吸收效果。但需注意的是,环氯茚酸并非适合所有人,部分患者可能出现副作用,如浮肿、血尿素氮水平上升、蛋白尿、粒细胞减少以及皮疹等。因此,消化道溃疡、肝肾疾病患者以及对阿司匹林类药物过敏者应避免使用。
在使用时,必须遵守医生的建议,切勿与消炎镇痛药物同时服用,以防止可能的药物相互作用。环氯茚酸的常见制剂为片剂,每片剂量为毫克。它的通用名称为环氯茚酸,英文名为Clidanac,还有其他中文别名克力丹酸,以及英文别名Britai和Indanal。
å¦ä½ç¼è¯SQLite-How To Compile SQLite
SQLiteæ¯ANSI-Cçæºä»£ç ãå¨ä½¿ç¨ä¹åå¿ é¡»è¦ç¼è¯ææºå¨ç ãè¿ç¯æç« æ¯ç¨äºåç§ç¼è¯SQLiteæ¹æ³çæåã
è¿ç¯æç« ä¸å å«ç¼è¯SQLiteçæ¯ä¸ªæ¥éª¤çåé¦ï¼é£æ ·å¯è½ä¼å°é¾å 为æ¯ç§å¼ååºæ¯é½ä¸åãæ以è¿ç¯æç« æè¿°åéè¿°äºç¼è¯Sqliteçååãå ¸åçç¼è¯å½ä»¤å·²ç»ä½ä¸ºä¾åæä¾äºï¼ä»¥ææåºç¨å¼åè è½å¤ä½¿ç¨è¿äºä¾åä½ä¸ºå®æä»ä»¬èªå·±å®å¶çç¼è¯è¿ç¨ççä¸ä¸ªæåãæ¢å¥è¯è¯´ï¼è¿ç¯æç« æä¾äºæ³æ³åè§è§£ï¼èä¸æ¯äº¤é¥åç解å³æ¹æ³ã
èåVSåç¬æºæ件
Sqliteæ¯ç±è¶ è¿ä¸ç¾ä¸ªcæºç æ件以åä¼å¤çç®å½ä¸çèæ¬æ建çãSqliteçå®ç°æ¯çº¯ç²¹çANSI-Cï¼ä½æ¯è®¸å¤Cè¯è¨æºä»£ç æ件æ¯ç±è¾ å©çCç¨åºçææè 转æ¢æ¥çï¼å¹¶ä¸AWKï¼SEDåTCLèæ¬ä¼èåå°å®æçsqliteåºä¸ã对Sqliteæ建éè¦çCç¨åºå转æ¢åå建Cè¯è¨æºç æ¯ä¸ä¸ªå¤æçè¿ç¨ã
为äºç®åè¿äºï¼sqliteä¹éè¿ä¸ä¸ªé¢æå çå并åçæºç æ件ï¼sqlite3.cãè¿ä¸ªå并æ件æ¯ä¸ä¸ªANSI-Cæºç å®ç°æ´ä¸ªSQLiteåºçå¯ä¸æ件ãå并åçæ件æ´å®¹æå¤çãææçä¸è¥¿é½å å«å¨è¿ä¸ä¸ªæ件éï¼æ以å¾å®¹æè¿å ¥ä¸ä¸ªæ´å¤§çCæè C++ç¨åºçæºç æ ãææç代ç çæå转æ¢æ¥éª¤é½å·²ç»å®ç°äºï¼å æ¤æ²¡æè¾ å©çCç¨åºéè¦å»é ç½®ååå¼ï¼ä¹æ²¡æèæ¬éè¦å»è¿è¡ã并ä¸ï¼å æ¤ææåé½å å«å¨ä¸ä¸ªç¿»è¯åå ï¼ç¼è¯å¨å¯ä»¥åæ´å¤é«çº§çä¼åä»èæå5%å°%çæ§è½ãå 为è¿äºåå ï¼èååçæºç æ件sqlite3.c对ææç¨åºæ¥è®²é½æ¯å¼å¾æ¨èçã
æ¨èææçåºç¨ç¨åºä½¿ç¨èåæ件ã
ç´æ¥ä»åç¬çæºç æ件ä¸æ建sqliteå½ç¶å¯ä»¥ï¼ä½æ¯å¹¶ä¸æ¨èã对ä¸äºç¹æ®çåºç¨ç¨åºï¼å¯è½éè¦ä¿®æ¹æ建ç¨åºå»å¤ç使ç¨é£äºä»ç½ç«ä¸ä¸è½½çé¢æ建çæºç æ件ä¸è½å®æçæ åµã对äºè¿äºæ åµï¼æ¨èæ建å使ç¨ä¸ä¸ªå®å¶è¿çå并æ件ãæ¢å¥è¯è¯´ï¼å³ä½¿ä¸ä¸ªå·¥ç¨éè¦ä»¥åç¬çæºç æ件æ建sqliteï¼ä»ç¶æ¨è使ç¨ä¸ä¸ªèååçæºç æ件ä½ä¸ºä¸ä¸ªä¸é´æ¥éª¤ã
ç¼è¯å½ä»¤è¡æ¥å£ï¼CLIï¼
æ建å½ä»¤è¡æ¥å£éè¦ä¸ä¸ªæºç æ件ï¼
sqlite3.c:Sqliteèåçæºç æ件
sqlite3.h:å¹é sqlite3.c以åå®ä¹sqliteçcè¯è¨æ¥å£ç头æ件
shell.c:å½ä»¤è¡æ¥å£ç¨åºæ¬èº«ãè¿ä¸ªcæºç æ件å å«ä¸ä¸ªmain()çä¾ç¨åæ¯è½®å¾ªç¯çç¨æ·è¾å ¥çæ示符并å°è¾å ¥ä¼ ç»sqliteæ°æ®åºå¼æç¨äºå¤çã
ææçä¸è¿°æºç çä¸ä¸ªæ件é½è¢«å å«å¨ä¸è½½é¡µé¢çamalgamation tarballä¸ã
为äºæ建CLIï¼ç®åçå°è¿ä¸ä¸ªæ件æ¾ç½®å¨ç¸åçç®å½ä¸ç¶åä¸èµ·ç¼è¯ä»ä»¬ãç¨MSVCï¼
cl shell.c sqlite3.c -Fesqlite3.exe
å¨unixç³»ç»ä¸ï¼æè å¨windowsä¸ç¨cygwinæè mingw+msysï¼å ¸åçå½ä»¤ä¼æäºåè¿æ ·ï¼
gcc shell.c sqlite3.c -lpthread -ldl
为äºSQLite线ç¨å®å ¨ï¼éè¦pthreadsåºãä½æ¯å 为CLIæ¯ä¸ä¸ªå线ç¨çï¼æ们å¯ä»¥æ示SQLiteæ建ä¸ä¸ªé线ç¨å®å ¨çåºå¹¶å æ¤æ¤ç»¿pthreadsåºï¼
gcc -DSQLITE_THREADSAFE=0 shell.c sqlite3.c -ldl
-ldlåºæ¯å¨æ¯æå¨æè£ è½½æ¶éè¦ï¼ä¾å¦sqlite3_load_extension() æ¥å£åload_extension()
SQL functionãå¦æè¿äºç¹æ§é½ä¸è¦æ±ï¼é£ä¹æ们ä¹å¯ä»¥ä½¿ç¨SQLITE_OMIT_LOAD_EXTENSIONç¼è¯æ¶é´é项忽ç¥ä»ä»¬ã
gcc -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION shell.c sqlite3.c
æ人å¯è½æ³è¦æä¾å ¶ä»çç¼è¯æ¶é´é项(compile-time options)ï¼ä¾å¦SQLITE_ENABLE_FTS3å»å ¨ææ¬æç´¢æè SQLITE_ENABLE_RTREEç¨äºR*æ æç´¢å¼ææ©å±ãèæ人å°æ£å¸¸æå®ä¸äºç¼è¯ä¼åå¼å ³ãï¼é¢ç¼è¯çCLIå¯ä»¥ä»éæ©sqliteç½ç«ä¸ä½¿ç¨â-Osâä¸è½½ä¸æ¥ï¼ææ æ°ç§å¯è½çåæ°å¨è¿éã
å ³é®ç¹å¨è¿éï¼æ建CLIéè¦ç¼è¯ä¸èµ·ä¸¤ä¸ªCè¯è¨æ件ãshell.cæ件å å«å ¥å£çå®ä¹åç¨æ·è¾å ¥çloopï¼èsqliteèåæ件sqlite3.cå å«å®æ´çsqliteåºçå®ç°ã
ç¼è¯TCLæ¥å£
sqliteçtclæ¥å£æ¯ä¸ä¸ªå°ç模å被添å å°ä¸è¬çèåæ件ä¸ãç»ææ¯ä¸ä¸ªæ°çèååçæºç æ件ï¼ç§°ä¹ä¸ºâtclsqlite3.câãè¿ä¸ªæºç æ件æ¯çæä¸ä¸ªå¯ä»¥ä½¿ç¨TCL
loadå½ä»¤å»å è½½å°ä¸ä¸ªæ åçtclshæè wishä¸ï¼æè éçsqliteæ建æåçæä¸ä¸ªåç¬å¯ä¸çtclshçå ±äº«åºæéè¦çãä¸ä¸ªtclçèåçå¯æ¬è¢«å å«å¨ä¸è½½é¡µçTEA
tarballä¸ä½ä¸ºä¸ä¸ªæ件ã
为äºçæä¸ä¸ªlinuxä¸çsqliteçTCL-loadableåº,ä¸é¢çå½ä»¤éè¦æ»¡è¶³ï¼
gcc -o libtclsqlite3.so -shared tclsqlite3.c -lpthread -ldl -ltcl
ä¸å¹¸çæ¯æ建Mac OS X å Windowsçå ±äº«åºå¹¶ä¸æ¯å¦æ¤ç®åã对äºè¿äºå¹³å°æ好使ç¨å å«å¨TEA tarballä¸çconfigureèæ¬åmakefile.
为äºçæä¸ä¸ªåç¬çtclshï¼å¯ä»¥ç¨äºsqliteéæé¾æ¥ï¼ä½¿ç¨å¦ä¸çç¼è¯å¨è°ç¨ï¼
gcc -DTCLSH=1 tclsqlite3.c -ltcl -lpthread -ldl -lz -lm
è¿éçæå·§æ¯-DTCLSH=1é项ãsqliteçTCLæ¥å£æ¨¡åå å«ä¸ä¸ªmainçè¿ç¨ï¼ç¨äºåå§åä¸ä¸ªTCL解éå¨å¹¶å¨ä»¥-DTCLSH=1ç¼è¯åè¿å ¥å°ä¸ä¸ªå½ä»¤è¡loopãä¸è¿°å½ä»¤å¯ä»¥å·¥ä½å¨LinuxåMac
OS X,è½ç¶ææ¶å¯è½éè¦ä¾èµäºå¹³å°è°æ´åºé项以åç¼è¯çTCLçåªä¸ä¸ªçæ¬ã
æ建èåæ件
ä¸è½½é¡µæä¾çsqliteèåæ件ççæ¬å¯¹å¤§å¤æ°ç¨æ·æ¥è¯´æ¯è¶³å¤çãç¶èï¼ä¸äºå·¥ç¨å¯è½æ³è¦æè éè¦æ建ä»ä»¬èªå·±çèåæ件ãä¸ä¸ªå¸¸è§çæ建ä¸ä¸ªå®å¶çèåæ件ççç±æ¯ä¸ºäºä½¿ç¨ç¹å®çcompile-time optionsæ¥å®å¶sqliteåºãåæ³sqliteèåæ件ä¸å å«äºè®¸å¤C代ç ç±è¾ å©ç¨åºåèæ¬çæã许å¤çç¼è¯æ¶é´é项影åè¿ä¸æå£ä»£ç èä¸å¿ é¡»å¨èåæ件ç»è£ åæä¾ç»ä»£ç çæå¨ãè¿ä¸ç³»åå¿ é¡»ä¼ ç»ä»£ç çæå¨çç¼è¯æ¶é´ç¸å ³çé项ä¼ä½¿å¾sqliteçåå¸çæ¬åä¸ç¸åï¼ä½æ¯å¨åè¿è¾¹æç« çæ¶åï¼ä»£ç çæå¨éè¦ç¥éçè¿ç»é项å æ¬ï¼
SQLITE_ENABLE_UPDATE_DELETE_LIMIT
SQLITE_OMIT_ALTERTABLE
SQLITE_OMIT_ANALYZE
SQLITE_OMIT_ATTACH
SQLITE_OMIT_AUTOINCREMENT
SQLITE_OMIT_CAST
SQLITE_OMIT_COMPOUND_SELECT
SQLITE_OMIT_EXPLAIN
SQLITE_OMIT_FOREIGN_KEY
SQLITE_OMIT_PRAGMA
SQLITE_OMIT_REINDEX
SQLITE_OMIT_SUBQUERY
SQLITE_OMIT_TEMPDB
SQLITE_OMIT_TRIGGER
SQLITE_OMIT_VACUUM
SQLITE_OMIT_VIEW
SQLITE_OMIT_VIRTUALTABLE
为äºæ建ä¸ä¸ªå®å¶çèåæ件ï¼å ä¸è½½åå§çç¬ç«æºç æ件å°ä¸ä¸ªunixæè ç±»unixå¼åå¹³å°ãç¡®å®è·åçåå§æºç æ件ä¸æ¯âé¢ç¼è¯è¿çæºæ件âãä»»ä½äººé½å¯ä»¥éè¿å°ä¸è½½é¡µæè ç´æ¥ä»configuration management system.è·åå®æ´çä¸å¥åå§æºç æ件ã
å设sqliteæºç æ 被åå¨ä¸ä¸ªå为âsqliteâçç®å½ä¸ã计åæ建ä¸ä¸ªå¹³è¡ç®å½ä¸çå为âbldâçèåæ件ãé¦å éè¿è¿è¡sqliteæºç æ ç§çconfigureèæ¬è¿è¡æè éè¿å¶ä½ä¸ä»½æºç æ 顶å±ççmakfile模æ¿çä¸ä»½ï¼æ¥æ建ä¸ä¸ªåéçmakefile.ç¶åæå¨ç¼è¾è¿ä¸ªMakfileå»å å«éè¦çç¼è¯æ¶é´ç¸å ³çé项ãæç»è¿è¡ï¼
make sqlite3.c
å¨windowsä¸ä½¿ç¨MSVC:
nmake /f Makefile.msc sqlite3.c
sqlite3.cçmake
targetä¼èªå¨æé ä¸è¬çâsqlite3.câå并çæºç æ件ï¼ä»¥åå®ç头æ件âsqlite3.hâï¼åå å«TCLæ¥å£çèåæºç æ件âtclsqlite3.câãä¹åï¼éè¦çæ件å¯ä»¥è¢«æ·è´å°æ件ç®å½ä¸ç¶åæ ¹æ®ä¸è¿°å¾åçè¿ç¨ç¼è¯ã
æ建ä¸ä¸ªwindowsçå¨æé¾æ¥åºDLL
为äºå¨windowsæ建ä¸ä¸ªsqliteçdll使ç¨ï¼é¦å è·å对åºçèåè¿çæºç æ件ï¼sqlit3.cåsqlite.hãè¿äºå¯ä»¥ä»SQLite websiteä¸ä¸è½½æè åä¸è¿°åç¥çä¸æ ·å»å®å¶çæã
使ç¨å·¥ä½ç®å½ä¸çæºç æ件ï¼ä¸ä¸ªdllå¯ä»¥å¨msvcä¸ä½¿ç¨å¦ä¸å½ä»¤çæï¼
cl sqlite3.c -link -dll -out:sqlite3.dll
ä¸è¿°å½ä»¤éè¦è¿è¡å¨msvcçMSVC Native Tools Command
Prompt.å¦ä½ä½ å·²ç»å¨æºå¨ä¸å®è£ äºmsvcï¼ä½ å¯è½æå¤ä¸ªçæ¬çè¿ç§å½ä»¤æ示符ï¼é对äºxåxçèªå¸¦æ建çï¼æè 交åç¼è¯å°ARMçãä¾èµè¦æ±çDLLå»ä½¿ç¨å¯¹åºåéçå½ä»¤æç¤ºç¬¦å·¥å ·ã
å¦æ使ç¨MinGWç¼è¯å¨ï¼å½ä»¤æ¯è¿æ ·çï¼
gcc -shared sqlite3.c -o sqlite3.dll
注æMinGWåªçæä½çdllãå¦æä¸ä¸ªåå¼çMinGWå·¥ç¨å¯ä»¥ç¨æ¥çæä½çdllãå¯ä»¥æ¨æå ¶å½ä»¤è¡è¯æ³æ¯ç±»ä¼¼çãéè¦æ³¨æçæ¯æè¿çMSVCççæ¬çæçDLLså¯è½ä¸è½å·¥ä½å°WinXPæè æ´æ©çæ¬çwindowsä¸ãå æ¤ä¸ºäºæ大é度çå ¼å®¹ä½ ççæçdllï¼æ¨èMinGWãä¸ä¸ªå¥½çç»éªæ³åæ¯ä½¿ç¨MinGWå»çæä½çdllsï¼ä½¿ç¨msvcå»çæä½çdllsã
数据库中间件-cetus源码介绍
数据库中间件Cetus的源码介绍将重点放在其内部流程的解析上。从启动开始,Cetus的执行流程主要从src/mysql-proxy-cli.c文件的main函数出发,调用main_cmdline函数。在正常情况下,启动service后,流程会进入main_cmdline函数中的chassis_mainloop。
chassis_mainloop函数将调用cetus_master_process_cycle,该过程一直传递chassis结构,其包含关键元素。在cetus_master_process_cycle中,程序开启worker_process,主要在cetus_spawn_process函数中进行,之后进入cetus_worker_process_cycle进行初始化。
worker_process通过死循环调用主进程chassis_event_loop,并监听客户端消息。在执行流程中,会经过event_base_loop和ev_run等函数,进一步处理事件。
具体任务处理流程从event_base_loop开始,调用ev_run、ev_invoke_pending、ev_x_cb_io、ev_x_cb,最终到达network_mysqld_con_handle处理传入的SQL语句,并将它们赋值给con->orig_sql。接下来调用normal_read_query_result函数,此函数调用network_mysqld_read_rw_resp处理与后端数据库的消息,并基于返回结果进行后续操作。
总结,Cetus源码中,从启动至执行流程,再到任务处理,构成了一个完整的数据库中间件执行逻辑。其核心在于通过一系列函数调用,实现消息的传递、处理和最终反馈,确保数据的高效、准确处理。流程清晰,结构严谨,体现了Cetus在数据库中间件领域的专业性和高效性。
wpa_supplicant-2.源码分析
本文将深入剖析wpa_supplicant-2.源码,重点关注其关键函数在实现Station & P2P模式中的作用。首先,在wpa_supplicant/main.c的主函数main()中,程序主要负责四大任务:解析命令行输入的参数,这是初始化过程中的重要步骤。
调用wpa_supplicant_init()函数,启动wpa_supplicant的核心功能,进行初始化配置。
紧接着,wpa_supplicant_add_iface()函数被调用,这一步用于增加网络接口,以支持连接不同的网络。
最后,wpa_supplicant_run()函数被调用,使wpa_supplicant进入运行状态,开始监听和管理无线网络连接。
值得注意的是,wpa_supplicant的后台服务是wpa_cli命令使用的前提,只有当wpa_supplicant在后台运行时,用户才能通过wpa_cli命令进行配置和管理。具体到wpa_cli命令的下发,其背后的执行逻辑是调用wpa_ctrl_request函数来触发相应的操作。 通过这段代码的解读,我们可以更直观地理解wpa_supplicant在无线网络管理中的工作流程和关键函数交互。CListCList类的成员
CList类的成员提供了对有序列表的多种操作,以下是对这些成员功能的描述: 构造函数CList:用于创建一个空的有序列表。 访问头部元素:GetHead():返回列表的头部元素。该元素不能为空。
访问尾部元素:GetTail():返回列表的尾部元素。该元素不能为空。
移除头部元素:RemoveHead():从列表头部移除元素。
移除尾部元素:RemoveTail():从列表尾部移除元素。
添加头部元素:AddHead():将一个元素或另一个列表的所有元素添加到头部,生成新的头部。
添加尾部元素:AddTail():将一个元素或另一个列表的所有元素添加到尾部,生成新的尾部。
移除所有元素:RemoveAll():从列表中移除所有元素。
获取元素位置:GetHeadPosition():返回头部元素的位置。
GetTailPosition():返回尾部元素的位置。
遍历元素:GetNext():获取用于遍历下一个元素的方法。
GetPrev():获取用于遍历的前一个元素的方法。
获取或修改元素: CList类成员提供了对列表元素的获取和修改功能,便于用户对有序列表进行操作和管理。