Commit 8d669af7eff27e32f00bff131b0b1af3620a76b4

Authored by ly525
1 parent 7d6e21d1

docs: update Oracle Adapter

docs/.vuepress/config.js
@@ -59,7 +59,8 @@ module.exports = { @@ -59,7 +59,8 @@ module.exports = {
59 title: '🤝Ecosystem', 59 title: '🤝Ecosystem',
60 children: [ 60 children: [
61 '/zh/ecosystem/', 61 '/zh/ecosystem/',
62 - '/zh/ecosystem/backend-intergration' 62 + '/zh/ecosystem/backend-intergration',
  63 + '/zh/ecosystem/database-oracle'
63 ], 64 ],
64 }, 65 },
65 { 66 {
@@ -125,8 +126,8 @@ module.exports = { @@ -125,8 +126,8 @@ module.exports = {
125 title: '🤝社区生态-周边建设', 126 title: '🤝社区生态-周边建设',
126 children: [ 127 children: [
127 '/zh/ecosystem/', 128 '/zh/ecosystem/',
128 - '/zh/ecosystem/backend-intergration'  
129 - 129 + '/zh/ecosystem/backend-intergration',
  130 + '/zh/ecosystem/database-oracle'
130 ], 131 ],
131 }, 132 },
132 { 133 {
docs/zh/ecosystem/database-oracle.md 0 → 100644
  1 +# Oracle 适配([Strapi.js](https://strapi.io/))
  2 +> 本文作者[shaxm](https://github.com/shaxm), 特别感谢他的辛勤写作和探索
  3 +
  4 +以下适用于luban-h5的v1.8.1 以上版本
  5 +[1.8.1](https://github.com/ly525/luban-h5/compare/v1.8.0...v1.8.1) (2020-01-12)
  6 +
  7 +1. 安装 oracledb 模块
  8 +
  9 +```bash
  10 +npm install oracledb
  11 +```
  12 +
  13 +2. back-end\h5-api\config\environments\development\database.json
  14 +
  15 +> 注:username就是数据库的用户名,由于框架原因,创建数据库用户时要注意,用户名前后必须带半角双引号。
  16 +
  17 +
  18 +```javascript
  19 +{
  20 +  "defaultConnection": "default",
  21 +  "enabled": true,
  22 +  "connections": {
  23 +    "default": {
  24 +      "connector": "bookshelf",
  25 +      "settings": {
  26 +        "client": "oracledb",
  27 +        "connectString": "ip:port/orcl",
  28 +        "username": "\"luban\"",
  29 +        "password": "your password",
  30 +        "charset": "utf8"
  31 +      },
  32 +      "options": {
  33 +        "debug": true,
  34 +        "pool": {
  35 +          "acquireTimeoutMillis": 60000,
  36 +          "min": 0,
  37 +          "max": 7
  38 +        },
  39 +        "acquireConnectionTimeout": 600000,
  40 +        "useNullAsDefault": true,
  41 +        "fetchAsString": ["clob"]
  42 +      }
  43 +    }
  44 +  }
  45 +}
  46 +```
  47 +
  48 +3. back-end\h5-api\node_modules\bookshelf\lib\sync.js
  49 +
  50 +```javascript
  51 +// Sync
  52 +// ---------------
  53 +'use strict';
  54 +
  55 +const _ = require('lodash');
  56 +const Promise = require('bluebird');
  57 +const validLocks = ['forShare', 'forUpdate'];
  58 +
  59 +function supportsReturning(client = {}) {
  60 +  if (!client.config || !client.config.client) return false;
  61 +  return ['postgresql', 'postgres', 'pg', 'oracle', 'mssql', 'oracledb'].includes(client.config.client);
  62 +}
  63 +```
  64 +
  65 +4.back-end\h5-api\node_modules\strapi-connector-bookshelf\lib\knex.js
  66 +
  67 +```javascript
  68 +/* eslint-disable prefer-template */
  69 +// Array of supported clients.
  70 +const CLIENTS = [
  71 +  'pg',
  72 +  'mysql',
  73 +  'mysql2',
  74 +  'sqlite3',
  75 +  'mariasql',
  76 +  'oracle',
  77 +  'oracledb',
  78 +  'strong-oracle',
  79 +  'mssql',
  80 +];
  81 +```
  82 +
  83 +```
  84 +ssl: _.get(connection.settings, 'ssl', false),
  85 +timezone: _.get(connection.settings, 'timezone', 'utc'),
  86 +filename: _.get(connection.settings, 'filename', '.tmp/data.db'),
  87 +connectString: _.get(connection.settings, 'connectString'),
  88 +
  89 +增加oracledb的fetchAsString属性的支持,处理blob字段
  90 +// Resolve path to the directory containing the database file.
  91 +const fileDirectory = options.connection.filename
  92 + ? path.dirname(path.resolve(strapi.config.appPath, options.connection.filename))
  93 + : '';
  94 +
  95 +switch(options.client) {
  96 + case 'oracledb':
  97 + options.fetchAsString = _.get(connection.options, 'fetchAsString', []);
  98 + break;
  99 +```
  100 +
  101 +5. back-end\h5-api\node_modules\knex\lib\query\builder.js
  102 +
  103 +```javascript
  104 +增加空字符串判断逻辑
  105 + if (arguments.length === 2) {
  106 + value = operator;
  107 + operator = '='; // If the value is null, and it's a two argument query,
  108 + // we assume we're going for a `whereNull`.
  109 + if ((this.client.config.client === 'oracledb' && (typeof value === "undefined" || value === '')) || value === null) {
  110 + return this.whereNull(column);
  111 + }
  112 + } // lower case the operator for comparison purposes
  113 +
  114 +增加空字符串判断逻辑
  115 + // If the value is still null, check whether they're meaning
  116 + // where value is null
  117 + if ((this.client.config.client === 'oracledb' && (typeof value === "undefined" || value === '')) || value === null) {
  118 + // Check for .where(key, 'is', null) or .where(key, 'is not', 'null');
  119 + if (checkOperator === 'is' || checkOperator === 'is not') {
  120 + return this._not(checkOperator === 'is not').whereNull(column);
  121 + }
  122 + } // Push onto the where statement stack.
  123 +
  124 +6. back-end\h5-api\node_modules\strapi-connector-bookshelf\lib\mount-models.js
  125 +
  126 +```js
  127 +const getDatabaseName = connection => {
  128 + const dbName = _.get(connection.settings, 'database');
  129 + const dbSchema = _.get(connection.settings, 'schema', 'public');
  130 + switch (_.get(connection.settings, 'client')) {
  131 + case 'sqlite3':
  132 + return 'main';
  133 + case 'pg':
  134 + return `${dbName}.${dbSchema}`;
  135 + case 'mysql':
  136 + return dbName;
  137 + case 'oracledb':
  138 + return _.get(connection.settings, 'username').replace(/"/g, '');
  139 + default:
  140 + return dbName;
  141 + }
  142 +};
  143 +```
  144 +
  145 +7. back-end\h5-api\node_modules\strapi-connector-bookshelf\lib\buildDatabaseSchema.js
  146 +
  147 +```javascript
  148 +const uniqueColName = (table, key) => generateCombinedName('unique', table, key); //`${table}_${key}_unique`;
  149 +
  150 +function generateCombinedName(postfix, name, subNames) {
  151 +  const crypto = require('crypto');
  152 +  const limit = 30;
  153 +  if (!Array.isArray(subNames)) subNames = subNames ? [subNames] : [];
  154 +  const table = name.replace(/\.|-/g, '_');
  155 +  const subNamesPart = subNames.join('_');
  156 +  let result = `${table}_${
  157 +    subNamesPart.length ? subNamesPart + '_' : ''
  158 +  }${postfix}`.toLowerCase();
  159 +  if (result.length > limit) {
  160 +    console.log(
  161 +      `Automatically generated name "${result}" exceeds ${limit} character ` +
  162 +        `limit for Oracle. Using base64 encoded sha1 of that name instead.`
  163 +    );
  164 +    // generates the sha1 of the name and encode it with base64
  165 +    result = crypto
  166 +      .createHash('sha1')
  167 +      .update(result)
  168 +      .digest('base64')
  169 +      .replace('=', '');
  170 +  }
  171 +  return result;
  172 +}
  173 +```