Skip to main content
O SDK Rust está em alpha — espere mudanças incompatíveis de API entre versões. As capabilities Preview são adicionalmente instáveis do lado do servidor: suas ABIs podem mudar entre versões do servidor. Uma extensão compilada contra uma capability Preview pode falhar ao carregar após uma atualização do servidor.
As capabilities Preview são recursos do servidor expostos às extensões antes que suas APIs sejam finalizadas. O SDK Rust envolve quatro delas: variáveis de status, variáveis de sistema, threads de trabalho em segundo plano e acesso ao keyring. Esta página cobre como declarar e usar cada uma a partir do Rust. Para o conceito, o nível Preview e as capabilities que existem apenas em C++, consulte Capabilities Preview.

Pré-requisitos

Uma extensão que usa qualquer capability Preview só instala quando vsql_allow_preview_extensions está em ON:
Consulte Habilitando o Nível Preview para os detalhes, incluindo por que SET GLOBAL é rejeitado para essa variável. Você também precisa de uma configuração Rust funcional para extensões — o passo a passo Criando Extensões em Rust cobre a toolchain, o cargo-vsql e o seu primeiro bloco extension!.

O Que o SDK Rust Envolve

As demais capabilities Preview — auth, mysql_services, sql_query, statement_event e a ABI de armazenamento de coluna — são exclusivas do C++ hoje. Use o SDK C++ se você precisar de uma delas.

Padrão de Registro

Declare cada capability como um static e então liste-a por referência na seção requires: de extension! — o equivalente Rust do .with() do SDK C++:
O servidor popula o objeto de capability no momento do carregamento; antes disso, seus métodos de acesso relatam a capability como indisponível em vez de travar. O static é obrigatório — o servidor mantém pointers para dentro da capability durante toda a vida da extensão.

Variáveis de Status

A capability status_var expõe contadores de propriedade da extensão através de SHOW GLOBAL STATUS. Sua extensão é dona do armazenamento como atômicos 'static e escreve neles; o servidor lê através dos pointers cada vez que a variável de status é consultada. Declare cada variável como um StatusVarSpecInt respaldado por um AtomicI64, ou Double respaldado pelo AtomicF64 do SDK (a biblioteca padrão do Rust não tem um f64 atômico, então o SDK fornece um com new, load e store):
Após o INSTALL EXTENSION, as variáveis aparecem com o nome da extensão como prefixo:

Variáveis de Sistema

A capability sys_var registra variáveis de sistema do MySQL de propriedade da sua extensão. Há suporte para três tipos: Bool, Int (com limites min/max) e Str. Todo spec carrega um nome, um comentário mostrado nos metadados de SHOW VARIABLES, um valor padrão e um callback on_change opcional. Nomes e valores padrão de string são valores &'static CStr — escreva-os como literais de string C (c"enabled"):
A seção funcs: deve estar presente antes de requires:, mesmo quando vazia. Após a instalação, as variáveis ficam endereçáveis com o nome da extensão como prefixo:

Reagindo a Mudanças

on_change é um callback C bruto, invocado pelo servidor depois que uma variável é definida. O servidor o chama enquanto mantém seu bloqueio global de variáveis de sistema, então mantenha-o rápido e não gere panic — um panic aqui atravessa a fronteira da FFI. O callback recebe um *const vef_sys_var_change_t da camada de ABI bruta:
Chamar SysVarCapability::get ou SysVarCapability::set, executar SQL ou esperar por uma thread que faça qualquer um dos dois causa deadlock nesse bloqueio. Mantenha o callback restrito a operações de controle interno nos seus próprios statics, como acima, e entregue o trabalho que precisa de SQL a uma thread de trabalho.
Conecte-o a um spec com on_change: Some(on_enabled_change).

Lendo e Escrevendo a partir do Código da Extensão

SysVarCapability também expõe get() e set() para acesso programático através do servidor (de forma que a validação de intervalo e a persistência sejam tratadas para você). set() recebe um argumento scope que seleciona a persistência: null altera apenas o valor em execução, então ele reverte na reinicialização; "PERSIST" altera o valor em execução e o escreve na configuração persistida; "PERSIST_ONLY" escreve na configuração persistida sem tocar no valor em execução, então ele se aplica na próxima reinicialização. Ambos são métodos FFI unsafe que recebem strings C terminadas em NUL, e ambos usam a convenção C invertida: Some(false) significa sucesso, Some(true) significa que o servidor relatou um erro, e None significa que a capability está indisponível. Em um get bem-sucedido, o servidor escreve uma string alocada com malloc que você deve liberar com o free() do C. O exemplo vsql_sys_var mostra o padrão completo, incluindo o extern do free e os comentários de segurança.

Thread de Trabalho

A capability thread_worker executa uma função que você fornece em uma thread em segundo plano gerenciada pelo servidor. O servidor registra uma variável de sistema de controle no momento do carregamento; enquanto ela está em ON, sua função de trabalho é chamada em um temporizador periódico, na prontidão de um descritor de arquivo, ou em transições de habilitação/desabilitação. Sua função de trabalho é Rust seguro e simples:
ThreadWorkerCapability::new recebe a função de trabalho, um sufixo de nome de thread, o intervalo inicial de espera e um nome alternativo opcional para a variável de controle. Quando o nome alternativo é None, a variável de controle se chama {suffix}_enabled e é registrada sob o prefixo da extensão:

Wakeups

WakeupReason diz por que o servidor chamou: Enable, Periodic, PollFd ou Disable. Seu valor de retorno ajusta o próximo wakeup:
  • NextWakeup::unchanged() — mantém o intervalo de espera e o poll fd atuais.
  • NextWakeup::after(duration) — acorda novamente após duration.
  • Defina o campo poll_fd com um descritor de arquivo maior que zero para também acordar quando ele ficar pronto para leitura, ou com -1 para limpar um que tenha sido definido antes.
Uma Duration de comprimento zero colapsa para “sem mudança” — a ABI C subjacente reserva o 0 para isso, então um wakeup instantâneo não pode ser expresso. Se a função de trabalho gerar panic, o SDK captura o panic na fronteira da FFI e trata a chamada como se ela retornasse NextWakeup::unchanged() — o worker continua em execução. O parâmetro ThreadHandle está reservado para abrir sessões SQL a partir do worker assim que a capability sql_query for portada para o Rust; ele ainda não tem métodos.

Acesso ao Keyring

A capability keyring lê e escreve segredos armazenados no componente keyring do MySQL — chaves de API, chaves de criptografia, qualquer coisa que não deveria ficar em uma tabela. Um componente keyring (por exemplo, component_keyring_file) deve estar instalado no servidor; sem um, toda leitura e escrita falha com KeyringError::NoComponent.
read(data_id, auth_id, buf) preenche o buffer que você passa e retorna Ok(Some(n)) com o comprimento do segredo, ou Ok(None) quando não existe nenhum segredo sob data_id — um resultado normal, não um erro. write(data_id, auth_id, data) retorna Ok(()) em caso de sucesso. auth_id é o usuário proprietário; passe None para chaves internas não associadas a um usuário específico. Ambos retornam Err(KeyringError) em caso de falha: CapabilityUnavailable (a capability nunca foi conectada), NoComponent (nenhum componente keyring no servidor) ou Other. O keyring não tem uma sondagem de tamanho: um segredo maior que o buffer que você passa para read volta como Ok(None), indistinguível de uma chave inexistente. Dimensione seu buffer para o maior segredo que você espera armazenar.

Próximos Passos

Capabilities Preview (C++)

O índice completo de capabilities, o nível Preview e as capabilities exclusivas do C++: auth, mysql_services, sql_query, statement_event e armazenamento de coluna.

Referência da API Rust

InValue, VdfReturn, extension!, func! e custom_type! — todos os campos.