使用CSS连接数据库的方式
故事背景
某公司招聘需求如下:
我们正在寻求可以 使用css连接数据库 的前端伙伴~
自从我上次开始一个高质量的“发帖”以来,已经有很长一段时间了,事实上,它已经很长一段时间了,那时候我的词汇表中可能还没有“水帖”这个词。
为此,我受到了一个早期项目的启发,该项目基于区块链初创公司将投资者的脸投影到3d立方体上让我想起了以前的互联网,那时一切都很奇怪。
好汉不提当年勇。所以今天,我将讨论如何管理我自己的新项目: sqlcss.xyz [1]
顾名思义,这就是使用css连接数据库的方式。不幸的是,它 只能在chrome中工作 ,但你可以提供任何你喜欢的sqlite数据库,并通过css查询它。
它是如何工作的?
首先我们需要用到一组被亲切地称为 houdini [2] 的api,它让你的浏览器能够通过javascript对象模型来控制css。换言之,这意味着您可以定制css样式、添加定制属性,等等。
可能这个作品最大的特性是 css paint worklet [3] ,它允许你在一个元素上“绘制”,就像你知道和喜欢的画布一样,并让浏览器把它当作css中的图像。这里有一些例子可以用来 演示houdini [4] 。
然而,这个工作集只提供了worker api的一个子集,而且画布上下文本身也被大量剥离。这样做的实际结果是,您的自定义css绘制代码提供了一个比您预期的更小的沙盒。
这意味着什么? 没有网络访问权限,因此可以和fetch和xmlhttprequest说再见了。在绘制上下文上没有drawtext功能。其他各种js api也消失了,以防你希望解决这些问题。
不过,不用担心。并非一切都完了。让我们把它分解成几个步骤。
1. 设置数据库
这必须是第一步,以便理解概念证明是否可行。
首先我们会借助于 sql.js [5] 。它实际上是一个通过emscripten编译成webassembly和老式asm.js的sqlite版本。不幸的是,我们不能使用wasm版本,因为它必须通过网络获取二进制文件。asm版本没有这个限制,因为所有的代码都可以在一个模块中使用。
虽然paintworklet限制了worker内部的网络访问,但你仍然可以导入代码,只要它是一个es6模块。这意味着文件中必须有一个导出语句。不幸的是,sql.js没有es6的版本,所以我自己修改了sql.js,使其能够顺利的被import进入项目。
现在到了关键时刻:我可以在我的工作包中建立一个数据库吗?
**成功了!**但没有任何数据,所以我们来解决这个问题。
2. 查询数据库
一开始最简单的方法就是设置一些假数据,sql.js有两个函数可以做到这一点。
我有了测试表,里面有一些值。我应该能够查询这个并获得这些值,尽管我不确定得到什么样的结构化查询结果。
正如预期的那样,结果已经出来了。不过,渲染展示通过css查询数据库的结果会更好。
3. 渲染结果,最简单的方法
我认为这就像在画布上写文本一样。这有多难,对吧?
不,那样就太简单了。这里的上下文与画布元素的上下文不同,它只提供了功能的一个子集。
当然,它仍然可以绘制路径和曲线,所以缺乏方便的api是一个障碍,但这一切都不是问题。
4. 不使用文本api创建文本
幸运的是,我们可以借助于 opentype.js [6] 所提供的解决方案。它可以解析一个字体文件,然后,给定一个文本字符串,生成每个字符的字母形式。这个操作的实际结果是一个表示字符串的路径对象,然后可以将其呈现到上下文中。
这次我不必修改opentype库来导入它,因为它已经可以从 jspm [7] 中获得。所以,如果你给jspm一个npm包,它会自动生成一个es6模块,你可以直接导入到你的浏览器中。这是非常棒的,因为我真的不想为了一个有趣的项目而使用打包工具。
但这里有一个问题——它想通过网络加载字体,而我不能这样做!嗨,挫败了!
……而且?它还有一个接受数组缓冲区的解析方法。我将用base64编码字体,然后在我的模块中解码它。
我告诉过你worklet也没有处理base64字符串的api吗?atob和btoa都没有!我也不得不为此找到一个普通的js实现。
我把这段代码放在它自己的文件中,因为它不太符合人体工程学……必须在剩下的代码旁边使用大约200kb的编码字体字符串。
这就是我为何要滥用es模块来加载我的字体的原因。
5. 渲染结果,另一种简单的方式
从现在起,所有繁重的工作都由opentype库来完成,所以我所需要做的就是用一点数学知识来对齐。
最好再来一些html和css看看发生了什么。
成功了!但这里没有足够的css,而且查询是硬编码的。
6. 通过css查询
如果必须使用css来查询数据库,那就更好了。事实上,这是我们可以在paint worker的上下文之外与其通信的唯一方式,因为没有与web worker一样的消息传递api。
为此,需要一个定制的css属性。定义inputproperties的好处是可以订阅该属性的更改,因此如果该属性的值发生更改,它将重新呈现。不需要设置任何订阅者自己。
这些css属性被称为类型化属性,但它们本质上被封装在一个特殊的cssproperty类中,而这个类本身并不是很有用。因此,你必须手动将其转换为字符串或数字或其他类似的使用它,如上所述。
现在对css做一个快速调整。
引号在这里被故意省略了,因为否则在将字符串传递给数据库之前,我必须将它们从字符串中删除。也就是说,这很有效!
任务完成!
如果你玩过sqlcss。你会注意到我并没有满足于此。在进行了一些重构之后,又进行了一些更改。
7. 导入数据库文件
硬编码数据库模式和实际数据,有点糟糕。它证明了这个概念,但我们肯定可以做得更好。
如果您可以查询任何您喜欢的数据库,只要您手边有数据库文件,那就太棒了。我只需要读取这个文件并对其进行base64编码,就像我对字体文件所做的那样。
我为此做了一个额外的css属性,在这个属性中,您可以将sqlite数据库作为base64编码的数据uri提供。data uri只是为了显示并确保它对dom是有效的,我将在worker层面解析这些东西。
最后一步是使其更易于查询,因为否则您必须进入调试器来操作元素的css。
8. 编写查询语句
这可能是项目中最简单的部分。自定义属性对于分号有一点问题,而sqlite并不关心末尾的分号是否被省略,所以最简单的做法是,如果在输入中找到它,就删除它。
从现在开始,您可以使用css导入和浏览您自己的数据库了!
我遗漏了一件事,就是所有这些查询结果特别多的时候,如何更好的渲染展示的问题。如果查询结果有很多,他们需要分开到单独的行。这与本文的主题-- 使用css连接到数据库 并没有太大关系,所以我认为在这里谈论这个问题并不合适,但如果你想进一步了解这个"荒谬"的概念, git上的代码都是可用的 [8] 。
译者补充
- sqlite是由c语言编写的嵌入式轻量级数据库,广泛用于ios和android的app中。若有读者想要在浏览器端应用sqlite,推荐使用sqlite的webassembly版--sql.js,基本与sqlite的使用没有太多区别。在实际项目使用中,还需特别注意sqlite的 安全性 问题。
- 为方便展示,特此截取本文作者所实现的css连接sqlite的部分demo如下:
关于文中所提到的jspm,这里引用其官网的介绍如下:jspm为导入映射提供了模块cdn和包管理,允许任何来自npm的包都可以直接在浏览器中加载,无需进一步的处理。
参考资料
[1]
sqlcss.xyz: https://www.sqlcss.xyz
[2]
css houdini: https://developer.mozilla.org/en-us/docs/web/guide/houdini
[3]
css paint worklet: https://developer.mozilla.org/en-us/docs/web/api/paintworklet
[4]
houdini how: https://houdini.how/
[5]
sql.js: https://sql.js.org/#/
[6]
opentype.js: https://opentype.js.org/
[7]
jspm: https://jspm.org/
[8]
sqlcss git: https://git.sr.ht/~mrlee/sqlcss
到此这篇关于使用css连接数据库的方式的文章就介绍到这了,更多相关css连接数据库内容请搜索以前的文章或继续浏览下面的相关文章,希望大家以后多多支持!
推荐阅读
-
使用CSS连接数据库的方式
-
springboot中使用jpa下hibernate的ddl-auto方式
-
springboot中使用jpa下hibernate的ddl-auto方式
-
python访问数据库语句(python连接数据库的方法)
-
django单元测试使用正确数据库(django框架的特点)
-
使用CSS连接数据库的方式
-
css filter和getUserMedia的联合使用
-
python中为其他函数添加额外功能,而不修改源代码的方式-------装饰器的使用讲解及代码示例(类似于java的装饰设计模式)
-
PostGre/GreenPlum中interval在循环中的使用 博客分类: 数据库
-
PostGre/GreenPlum中interval在循环中的使用 博客分类: 数据库