hughcube/laravel-ots

Installs: 5 472

Dependents: 1

Suggesters: 0

Security: 0

Stars: 0

Watchers: 1

Forks: 0

Open Issues: 0

pkg:composer/hughcube/laravel-ots

v1.2.0 2026-02-05 08:52 UTC

README

Test Actions status StyleCI Code Coverage Scrutinizer Code Quality Code Intelligence Status PHP Versions Supported Latest Stable Version Total Downloads License Latest Unstable Version composer.lock available

Laravel OTS 是一个功能完整的阿里云表格存储 (Tablestore/OTS) Laravel 适配器,提供了优雅的 API 来操作 OTS 服务。

功能特性

  • 完整的数据 CRUD 操作(单行、批量、范围查询)
  • 搜索索引支持(10+ 种查询类型)
  • Schema 管理(表、二级索引、搜索索引)
  • 本地事务支持
  • 并行扫描 (ParallelScan)
  • 数据流 (Stream) 处理
  • Laravel 缓存驱动 + 分布式锁
  • SQL 查询支持(同步/异步)
  • Eloquent ORM 模型支持
  • Laravel Sanctum 集成

安装

composer require hughcube/laravel-ots -vvv

配置

config/database.phpconnections 数组中添加 OTS 连接配置:

'ots' => [
    'driver' => 'ots',
    'endpoint' => env('OTS_ENDPOINT'),
    'instance' => env('OTS_INSTANCE'),
    'access_key_id' => env('OTS_ACCESS_KEY_ID'),
    'access_key_secret' => env('OTS_ACCESS_KEY_SECRET'),
],

.env 文件中配置:

OTS_ENDPOINT=https://instance.cn-hangzhou.ots.aliyuncs.com
OTS_INSTANCE=instance
OTS_ACCESS_KEY_ID=your_access_key_id
OTS_ACCESS_KEY_SECRET=your_access_key_secret

使用指南

获取连接

use HughCube\Laravel\OTS\Ots;

// 获取默认连接
$connection = Ots::connection();

// 获取指定连接
$connection = Ots::connection('ots');

// 直接获取 OTSClient 实例
$otsClient = $connection->getOts();

数据操作

Query Builder

按主键查询单行

use HughCube\Laravel\OTS\Ots;

$row = Ots::connection()->table('users')
    ->primaryKey(['id' => 1])
    ->findByPrimaryKey();

按主键查询多行

$rows = Ots::connection()->table('users')
    ->findMany([
        ['id' => 1],
        ['id' => 2],
        ['id' => 3],
    ]);

插入数据

// 方式1:通过 primaryKeyColumns 定义主键结构
Ots::connection()->table('users')
    ->primaryKeyColumns([
        'id' => PrimaryKeyTypeConst::CONST_INTEGER,
    ])
    ->insert([
        'id' => 1,
        'name' => 'John',
        'email' => 'john@example.com',
    ]);

// 方式2:通过 primaryKey 指定主键值(其余字段自动作为属性列)
Ots::connection()->table('users')
    ->primaryKey(['id' => 1])
    ->insert([
        'name' => 'John',
        'email' => 'john@example.com',
    ]);

// 多主键表插入
Ots::connection()->table('orders')
    ->primaryKeyColumns([
        'user_id' => PrimaryKeyTypeConst::CONST_INTEGER,
        'order_id' => PrimaryKeyTypeConst::CONST_INTEGER,
    ])
    ->insert([
        'user_id' => 100,
        'order_id' => 1,
        'amount' => 99.99,
        'status' => 'pending',
    ]);

// 插入并返回自增ID
$id = Ots::connection()->table('users')
    ->primaryKeyColumns([
        'partition' => PrimaryKeyTypeConst::CONST_STRING,
        'id' => PrimaryKeyTypeConst::CONST_PK_AUTO_INCR,  // 自增主键
    ])
    ->insertGetId([
        'partition' => 'user',
        'name' => 'John',
        'email' => 'john@example.com',
    ]);

更新数据

Ots::connection()->table('users')
    ->primaryKey(['id' => 1])
    ->update([
        'name' => 'John Doe',
        'updated_at' => time(),
    ]);

删除数据

Ots::connection()->table('users')
    ->primaryKey(['id' => 1])
    ->delete();

条件写入(乐观并发控制)

// 期望行存在才更新
Ots::connection()->table('users')
    ->primaryKey(['id' => 1])
    ->expectExist()
    ->update(['name' => 'New Name']);

// 期望行不存在才插入
Ots::connection()->table('users')
    ->expectNotExist()
    ->insert(['id' => 1, 'name' => 'John']);

// 忽略行存在性检查
Ots::connection()->table('users')
    ->rowExistence(RowExistenceExpectationConst::CONST_IGNORE)
    ->insert(['id' => 1, 'name' => 'John']);

指定返回的列

$row = Ots::connection()->table('users')
    ->primaryKey(['id' => 1])
    ->attributeColumns(['name', 'email'])
    ->findByPrimaryKey();

范围查询

基础范围查询

$rows = Ots::connection()->table('logs')
    ->startKey(['user_id' => 1, 'timestamp' => 0])
    ->endKey(['user_id' => 1, 'timestamp' => INF_MAX])
    ->limit(100)
    ->getRange();

正向/反向查询

// 正向查询(从小到大)
$rows = Ots::connection()->table('logs')
    ->forward()
    ->startKey(['id' => 1])
    ->endKey(['id' => 100])
    ->getRange();

// 反向查询(从大到小)
$rows = Ots::connection()->table('logs')
    ->backward()
    ->startKey(['id' => 100])
    ->endKey(['id' => 1])
    ->getRange();

搜索索引查询

使用搜索索引

$query = Ots::connection()->table('products')
    ->useSearchIndex('products_index');

精确查询 (Term)

$rows = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchTerm('status', 'active')
    ->searchQuery();

IN 查询 (Terms)

$rows = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchTerms('category', ['electronics', 'books', 'clothing'])
    ->searchQuery();

模糊匹配查询 (Match)

$rows = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchMatch('description', '手机')
    ->searchQuery();

短语查询 (MatchPhrase)

$rows = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchMatchPhrase('title', 'iPhone 15')
    ->searchQuery();

前缀查询 (Prefix)

$rows = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchPrefix('name', 'App')
    ->searchQuery();

通配符查询 (Wildcard)

$rows = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchWildcard('name', '*phone*')
    ->searchQuery();

范围查询 (Range)

$rows = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchRange('price', 100, 500)  // 100 <= price <= 500
    ->searchQuery();

// 开区间
$rows = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchRange('price', 100, 500, false, false)  // 100 < price < 500
    ->searchQuery();

匹配所有 (MatchAll)

$rows = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchMatchAll()
    ->searchQuery();

存在性查询 (Exists)

检查字段是否存在值。

$rows = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchExists('description')  // 只返回有 description 字段的记录
    ->searchQuery();

嵌套查询 (Nested)

用于查询嵌套类型的字段。

// 使用回调构建嵌套查询
$rows = Ots::connection()->table('orders')
    ->useSearchIndex('orders_index')
    ->searchNested('items', function ($query) {
        $query->searchTerm('items.product_id', 'P001')
              ->searchRange('items.quantity', 1, 10);
    })
    ->searchQuery();

// 使用原生查询数组
$rows = Ots::connection()->table('orders')
    ->useSearchIndex('orders_index')
    ->searchNested('items', [
        'query_type' => QueryTypeConst::TERM_QUERY,
        'query' => [
            'field_name' => 'items.name',
            'term' => 'iPhone',
        ],
    ])
    ->searchQuery();

地理距离查询 (GeoDistance)

查找指定圆形范围内的地理位置。

$rows = Ots::connection()->table('stores')
    ->useSearchIndex('stores_index')
    ->searchGeoDistance('location', 31.2304, 121.4737, 5000)  // 上海市中心 5000 米范围内
    ->searchQuery();

地理边界框查询 (GeoBoundingBox)

查找矩形范围内的地理位置。

$rows = Ots::connection()->table('stores')
    ->useSearchIndex('stores_index')
    ->searchGeoBoundingBox(
        'location',
        31.3, 121.3,   // 左上角 (纬度, 经度)
        31.1, 121.6    // 右下角 (纬度, 经度)
    )
    ->searchQuery();

地理多边形查询 (GeoPolygon)

查找多边形范围内的地理位置。

$rows = Ots::connection()->table('stores')
    ->useSearchIndex('stores_index')
    ->searchGeoPolygon('location', [
        [31.2, 121.4],  // 点1 (纬度, 经度)
        [31.3, 121.5],  // 点2
        [31.2, 121.6],  // 点3
        [31.1, 121.5],  // 点4
    ])
    ->searchQuery();

组合查询 (简单 AND)

多个条件默认使用 AND 逻辑组合。

$rows = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchTerm('status', 'active')
    ->searchRange('price', 100, 500)
    ->searchMatch('description', '手机')
    ->limit(20)
    ->searchQuery();

布尔查询 (BoolQuery)

支持完整的布尔逻辑:must (AND)、should (OR)、must_not (NOT)、filter (过滤)。

// 复杂布尔查询示例:
// (status = 'active' OR status = 'pending') AND price > 100 AND NOT (category = 'test')
$rows = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchShould(function ($query) {
        $query->searchTerm('status', 'active');
    })
    ->searchShould(function ($query) {
        $query->searchTerm('status', 'pending');
    })
    ->minimumShouldMatch(1)  // 至少匹配一个 should 条件
    ->searchMust(function ($query) {
        $query->searchRange('price', 100, null);
    })
    ->searchMustNot(function ($query) {
        $query->searchTerm('category', 'test');
    })
    ->searchQuery();

must 条件 (AND)

$rows = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchMust(function ($query) {
        $query->searchTerm('status', 'active');
    })
    ->searchMust(function ($query) {
        $query->searchRange('price', 100, 500);
    })
    ->searchQuery();

should 条件 (OR)

$rows = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchShould(function ($query) {
        $query->searchTerm('category', 'electronics');
    })
    ->searchShould(function ($query) {
        $query->searchTerm('category', 'computers');
    })
    ->minimumShouldMatch(1)  // 至少匹配一个
    ->searchQuery();

must_not 条件 (NOT)

$rows = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchTerm('status', 'active')
    ->searchMustNot(function ($query) {
        $query->searchTerm('is_deleted', true);
    })
    ->searchQuery();

filter 条件 (无评分过滤)

$rows = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchMatch('description', '手机')  // 参与评分
    ->searchFilter(function ($query) {
        $query->searchTerm('status', 'active');  // 不参与评分,仅过滤
    })
    ->searchQuery();

异步搜索查询

$context = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchTerm('status', 'active')
    ->asyncSearchQuery();

// 稍后获取结果
$rows = $context->HWait();

SQL 查询

同步 SQL 查询

// 直接执行 SQL
$rows = Ots::connection()->sql("SELECT * FROM users WHERE id = 1");

// 使用 Query Builder 构建 SQL
$rows = Ots::connection()->table('users')
    ->where('status', 'active')
    ->where('age', '>', 18)
    ->sqlGet();

异步 SQL 查询

$context = Ots::connection()->asyncSql("SELECT * FROM users WHERE id = 1");

// 稍后获取结果
$rows = $context->HWait();

构建 SQL 字符串

$sql = Ots::connection()->table('users')
    ->where('status', 'active')
    ->toSql();
// 输出: SELECT * FROM users WHERE status = 'active'

Schema 操作

表操作

创建表

use HughCube\Laravel\OTS\Ots;
use HughCube\Laravel\OTS\Schema\Blueprint;

Ots::connection()->getSchemaBuilder()->create('users', function (Blueprint $table) {
    // 定义主键
    $table->integer('id')->primaryKey()->autoIncrement();
    $table->string('partition_key')->primaryKey();
});

创建表(带预定义属性列)

预定义属性列用于创建二级索引,必须在创建表时定义。

Ots::connection()->getSchemaBuilder()->create('orders', function (Blueprint $table) {
    // 定义主键
    $table->string('user_id')->primaryKey();
    $table->integer('order_id')->primaryKey()->autoIncrement();

    // 预定义属性列(用于二级索引)
    $table->definedString('status');       // 字符串类型
    $table->definedInteger('amount');      // 整数类型
    $table->definedDouble('price');        // 浮点数类型
    $table->definedBoolean('is_paid');     // 布尔类型
    $table->definedBlob('data');           // 二进制类型

    // 或者使用通用方法指定类型
    $table->definedColumn('category', DefinedColumnTypeConst::DCT_STRING);
});

删除表

Ots::connection()->getSchemaBuilder()->drop('users');

检查表是否存在

if (Ots::connection()->getSchemaBuilder()->hasTable('users')) {
    // 表存在
}

获取所有表

$tables = Ots::connection()->getSchemaBuilder()->getAllTables();

二级索引

创建全局二级索引

Ots::connection()->getSchemaBuilder()->createGlobalIndex(
    'users',           // 表名
    'users_email_idx', // 索引名
    function (Blueprint $table) {
        $table->string('email')->primaryKey();
        $table->integer('id')->primaryKey();

        // 定义索引包含的属性列
        $table->definedColumn('name');
        $table->definedColumn('created_at');
    }
);

创建本地二级索引

Ots::connection()->getSchemaBuilder()->createLocalIndex(
    'users',
    'users_status_idx',
    function (Blueprint $table) {
        $table->integer('id')->primaryKey();
        $table->string('status')->primaryKey();
    }
);

删除二级索引

Ots::connection()->getSchemaBuilder()->dropSecondaryIndex('users', 'users_email_idx');

搜索索引

创建搜索索引

use Aliyun\OTS\ProtoBuffer\Protocol\FieldType;

Ots::connection()->getSchemaBuilder()->createSearchIndex(
    'products',       // 表名
    'products_index', // 索引名
    [
        'field_schemas' => [
            ['field_name' => 'name', 'field_type' => FieldType::TEXT, 'analyzer' => 'single_word'],
            ['field_name' => 'description', 'field_type' => FieldType::TEXT, 'analyzer' => 'max_word'],
            ['field_name' => 'price', 'field_type' => FieldType::DOUBLE],
            ['field_name' => 'status', 'field_type' => FieldType::KEYWORD],
            ['field_name' => 'created_at', 'field_type' => FieldType::LONG],
        ],
    ]
);

列出搜索索引

$indexes = Ots::connection()->getSchemaBuilder()->listSearchIndexes('products');

检查是否有搜索索引

// 检查表是否有任何搜索索引
if (Ots::connection()->getSchemaBuilder()->hasSearchIndex('products')) {
    // 有搜索索引
}

// 检查是否有特定名称的搜索索引
if (Ots::connection()->getSchemaBuilder()->hasSearchIndex('products', 'products_index')) {
    // 指定的搜索索引存在
}

检查是否有二级索引

// 检查表是否有任何二级索引
if (Ots::connection()->getSchemaBuilder()->hasSecondaryIndex('users')) {
    // 有二级索引
}

// 检查是否有特定名称的二级索引
if (Ots::connection()->getSchemaBuilder()->hasSecondaryIndex('users', 'users_email_idx')) {
    // 指定的二级索引存在
}

查看搜索索引详情

$info = Ots::connection()->getSchemaBuilder()->describeSearchIndex('products', 'products_index');

删除搜索索引

Ots::connection()->getSchemaBuilder()->dropSearchIndex('products', 'products_index');

事务支持

OTS 支持本地事务,用于同一分区键下的多行原子操作。

基础事务用法

use HughCube\Laravel\OTS\Ots;

$connection = Ots::connection();

// 开始事务(需要指定分区键)
$transaction = $connection->beginLocalTransaction('users', ['partition_key' => 'pk_value']);

try {
    // 事务内操作
    $transaction->putRow([
        'table_name' => 'users',
        'primary_key' => [['id', 1], ['partition_key', 'pk_value']],
        'attribute_columns' => [['name', 'John']],
    ]);

    $transaction->updateRow([
        'table_name' => 'users',
        'primary_key' => [['id', 2], ['partition_key', 'pk_value']],
        'update_of_attribute_columns' => [
            'PUT' => [['balance', 100]],
        ],
    ]);

    // 提交事务
    $transaction->commit();
} catch (\Exception $e) {
    // 回滚事务
    $transaction->rollback();
    throw $e;
}

使用回调方式

$connection->localTransaction('users', ['partition_key' => 'pk_value'], function ($transaction) {
    $transaction->putRow([...]);
    $transaction->updateRow([...]);
    // 回调结束自动提交,异常自动回滚
});

并行扫描

用于大数据量的高效扫描,支持多线程并行处理。

基础用法

use HughCube\Laravel\OTS\ParallelScanner;

$scanner = new ParallelScanner(Ots::connection(), 'products', 'products_index');

// 设置查询条件
$scanner->matchAll();

// 获取所有结果
$rows = $scanner->get();

// 获取计数
$count = $scanner->count();

高级配置

$scanner = new ParallelScanner(Ots::connection(), 'products', 'products_index');

// 设置扫描参数
$scanner->limit(1000)           // 每次扫描的行数
    ->aliveTime(60)             // 会话存活时间(秒)
    ->columns(['id', 'name'])   // 指定返回的列
    ->query($customQuery);      // 自定义查询条件

// 计算分片
$scanner->computeSplits();

// 获取分片扫描器
$partitionScanners = $scanner->getPartitionScanners();

// 扫描特定分片
$rows = $scanner->getPartition(0);

数据流处理

用于监听表数据变更,实现实时数据同步。

启用数据流

Ots::connection()->getSchemaBuilder()->enableStream('users', 24); // 24小时过期

读取数据流

use HughCube\Laravel\OTS\Stream\StreamReader;

$reader = new StreamReader(Ots::connection(), 'users');

// 获取所有分片的记录
$records = $reader->readAll();

// 收集所有记录
$allRecords = $reader->collect();

监听数据变更

$reader = new StreamReader(Ots::connection(), 'users');

// 长轮询监听(阻塞式)
$reader->watch(function ($records) {
    foreach ($records as $record) {
        // 处理变更记录
        $actionType = $record['action_type']; // PUT_ROW, UPDATE_ROW, DELETE_ROW
        $primaryKey = $record['primary_key'];
        $columns = $record['columns'] ?? [];
    }
});

禁用数据流

Ots::connection()->getSchemaBuilder()->disableStream('users');

缓存驱动

Laravel OTS 提供了完整的缓存驱动实现。

配置缓存

config/cache.php 中添加:

'stores' => [
    'ots' => [
        'driver' => 'ots',
        'connection' => 'ots',
        'table' => 'cache',
    ],
],

基础缓存操作

use Illuminate\Support\Facades\Cache;

// 设置缓存
Cache::store('ots')->put('key', 'value', 3600);

// 获取缓存
$value = Cache::store('ots')->get('key');

// 永久缓存
Cache::store('ots')->forever('key', 'value');

// 删除缓存
Cache::store('ots')->forget('key');

// 批量操作
Cache::store('ots')->putMany(['key1' => 'value1', 'key2' => 'value2'], 3600);
$values = Cache::store('ots')->many(['key1', 'key2']);

原子操作

// 自增/自减
Cache::store('ots')->increment('counter', 1);
Cache::store('ots')->decrement('counter', 1);

// 条件设置(不存在才设置)
Cache::store('ots')->add('key', 'value', 3600);

分布式锁

$lock = Cache::store('ots')->lock('processing', 10); // 10秒超时

if ($lock->get()) {
    try {
        // 执行需要锁保护的操作
    } finally {
        $lock->release();
    }
}

// 阻塞式获取锁
$lock->block(5, function () {
    // 获取到锁后执行
});

清理过期缓存

// 手动清理过期行
Cache::store('ots')->flushExpiredRows();

Eloquent ORM

定义模型

use HughCube\Laravel\OTS\Eloquent\Model;

class User extends Model
{
    protected $connection = 'ots';
    protected $table = 'users';

    // 定义主键列
    protected function getPrimaryKeyColumns(): array
    {
        return [
            ['id', PrimaryKeyTypeConst::CONST_INTEGER],
        ];
    }

    // 定义搜索索引(可选)
    protected $searchIndex = 'users_index';
}

使用模型

// 按主键查询
$user = User::find(['id' => 1]);

// 创建
$user = new User();
$user->id = 1;
$user->name = 'John';
$user->save();

// 更新
$user->name = 'John Doe';
$user->save();

// 删除
$user->delete();

Laravel Sanctum 集成

支持将 Sanctum 的 Personal Access Token 存储在 OTS 中,提供两种实现方式。

方式1:纯 OTS 表查询(推荐)

不依赖 Eloquent Model,直接操作 OTS 表。

use HughCube\Laravel\OTS\Sanctum\PersonalAccessToken;

// 配置(可选)
PersonalAccessToken::setConnectionName('ots');      // 设置 OTS 连接
PersonalAccessToken::setTableName('my_tokens');     // 设置表名

// 创建 Token
$token = PersonalAccessToken::createToken($user, 'api-token', ['read', 'write']);
echo $token->plainTextToken;  // 返回明文 token

// 查找 Token
$token = PersonalAccessToken::findToken($plainTextToken);
if ($token && $token->isValidAccessToken()) {
    $user = $token->tokenable();  // 获取关联用户
}

// 检查权限
if ($token->can('write')) {
    // 有写入权限
}

// 更新 Token
$token->last_used_at = now();
$token->save();

// 删除 Token
$token->delete();

方式2:Eloquent Model 方式

继承自 Laravel Sanctum 的 Model,兼容 Sanctum 的所有特性。

use HughCube\Laravel\OTS\Sanctum\EloquentPersonalAccessToken;

// 查找 Token
$token = EloquentPersonalAccessToken::findToken($plainTextToken);

// 其他操作与标准 Sanctum Model 相同

Sanctum 配置

AppServiceProvider 中注册:

use Laravel\Sanctum\Sanctum;
use HughCube\Laravel\OTS\Sanctum\PersonalAccessToken;

public function boot()
{
    Sanctum::usePersonalAccessTokenModel(PersonalAccessToken::class);
}

创建 Token 表

Ots::connection()->getSchemaBuilder()->create('personal_access_tokens', function (Blueprint $table) {
    $table->string('token')->primaryKey();    // token hash
    $table->string('app')->primaryKey();      // 应用名(分区键)
});

异步操作

大多数操作都支持异步模式,返回 RequestContext 对象,可以通过 HWait() 方法等待结果。

异步查询

// 异步单行查询
$context = Ots::connection()->table('users')
    ->primaryKey(['id' => 1])
    ->async()
    ->findByPrimaryKey(['id' => 1]);

// 异步搜索
$context = Ots::connection()->table('products')
    ->useSearchIndex('products_index')
    ->searchTerm('status', 'active')
    ->asyncSearchQuery();

// 异步 SQL
$context = Ots::connection()->asyncSql("SELECT * FROM users");

// 等待结果
$result = $context->HWait();

异步写入操作

// 异步插入
$context = Ots::connection()->table('users')
    ->primaryKeyColumns(['id' => PrimaryKeyTypeConst::CONST_INTEGER])
    ->asyncInsert(['id' => 1, 'name' => 'John']);

// 或者使用 async() 链式调用
$context = Ots::connection()->table('users')
    ->async()
    ->insert(['id' => 1, 'name' => 'John']);

// 异步插入并获取自增 ID
$context = Ots::connection()->table('users')
    ->primaryKeyColumns([
        'partition' => PrimaryKeyTypeConst::CONST_STRING,
        'id' => PrimaryKeyTypeConst::CONST_PK_AUTO_INCR,
    ])
    ->asyncInsertGetId(['partition' => 'user', 'name' => 'John']);

// 获取结果后解析自增 ID
$response = $context->HWait();
$id = $response['primary_key'][1][1] ?? null;

// 异步更新
$context = Ots::connection()->table('users')
    ->primaryKey(['id' => 1])
    ->asyncUpdate(['name' => 'John Doe']);

// 异步删除
$context = Ots::connection()->table('users')
    ->asyncDelete(['id' => 1]);

并行执行多个异步操作

// 同时发起多个异步请求
$contexts = [];
$contexts[] = Ots::connection()->table('users')->async()->findByPrimaryKey(['id' => 1]);
$contexts[] = Ots::connection()->table('users')->async()->findByPrimaryKey(['id' => 2]);
$contexts[] = Ots::connection()->table('users')->async()->findByPrimaryKey(['id' => 3]);

// 等待所有结果
$results = [];
foreach ($contexts as $context) {
    $results[] = $context->HWait();
}

通用异步处理

use HughCube\Laravel\OTS\OTS\Handlers\OTSHandlers;

$context = OTSHandlers::asyncDoHandle(
    Ots::connection()->getOts(),
    'getRow',
    $request
);

$response = $context->HWait();

直接访问 OTS SDK

对于未封装的高级功能,可以直接访问底层 OTSClient:

$otsClient = Ots::connection()->getOts();

// 调用任意 SDK 方法
$response = $otsClient->describeTable(['table_name' => 'users']);

// 或者通过 Connection 的魔术方法
$response = Ots::connection()->describeTable(['table_name' => 'users']);

工具方法

解析行数据

use HughCube\Laravel\OTS\Ots;

// 解析单行
$row = Ots::parseRow($response['row']);

// 解析自增 ID
$id = Ots::parseRowAutoId($response);

检查批量写入结果

if (!Ots::isBatchWriteSuccess($response)) {
    Ots::throwBatchWriteException($response);
}

Contributing

You can contribute in one of three ways:

  1. File bug reports using the issue tracker.
  2. Answer questions or fix bugs on the issue tracker.
  3. Contribute new features or update the wiki.

The code contribution process is not very formal. You just need to make sure that you follow the PSR-0, PSR-1, and PSR-2 coding guidelines. Any new code contributions must be accompanied by unit tests where applicable.

License

MIT