Valeu José,
É que achei que era um exemplo completo, mas foi apenas ilustrativo. Reajustei várias funções que tem retorno simples ou apenas mensagem, mas essas que retornam dados que não dá pra saber o que é pra um iniciando em SQL (begin at beginner) não sei como resolver:
ADOLOCAL(), NUMBERSQL(), DATESQL(), STRINGSQL(), ADORECCOUNT()
As primeiras lições já tudo ok, exemplo:
-Configurar Cliente
-Carregar arquivo com comando cQuery
-Filtrar
-Inserir
-Apagar
E um caminhão de coisa ainda a aprender.
NOTA: Na pasta contrib\hbmysql tem um exemplo similar, mas não consigo gerar a lib necessária pra usar aquele exemplo. O exemplo compila, mas a lib aqui no meu computador não. Então desisti daquele exemplo.
Carga do DBF para MySql/Postgres e LetoDbf juntos!
Moderador: Moderadores
- Jairo Maia
- Moderador
- Mensagens: 2820
- Registrado em: 16 Ago 2010 13:46
- Localização: Campinas-SP
- Curtiu: 2 vezes
Re: Carga do DBF para MySql/Postgres e LetoDbf juntos!
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
-
cleitonlc2025
- Usuário Nível 1

- Mensagens: 5
- Registrado em: 25 Out 2024 11:47
- Localização: Cariacica/ES
Re: Carga do DBF para MySql/Postgres e LetoDbf juntos!
Boas, estudando aqui também como usar harbour com sql, mais precisamente com postgresql.
Criei um trecho de código base com os principais comandos.
Criei um trecho de código base com os principais comandos.
Código: Selecionar todos
#require "hbpgsql"
PROCEDURE Main()
LOCAL conn, res
LOCAL cOpc := ""
LOCAL cDB := "minhabase"
CLS
? "Connecting to PostgreSQL (postgres database)..."
/* 1. Conecta no banco padrão postgres */
conn := PQconnectdb( ;
"dbname='postgres' " + ;
"host='localhost' " + ;
"user='postgres' " + ;
"password='postgres' " + ;
"port=5432" )
IF PQstatus( conn ) != CONNECTION_OK
? "Connection error:"
? PQerrorMessage( conn )
RETURN
ENDIF
/* 2. Verifica se o database existe */
res := PQexecParams( conn, ;
"SELECT 1 FROM pg_database WHERE datname = $1", ;
{ cDB } )
IF PQresultStatus( res ) != PGRES_TUPLES_OK
? "Erro ao verificar database"
? PQerrorMessage( conn )
RETURN
ENDIF
IF PQntuples( res ) == 0
? "Database nao existe, criando..."
PQexec( conn, "CREATE DATABASE " + cDB + " ENCODING 'UTF8'" )
ELSE
? "Database ja existe."
ENDIF
/* 3. Conecta na database final */
conn := PQconnectdb( ;
"dbname='" + cDB + "' " + ;
"host='localhost' " + ;
"user='postgres' " + ;
"password='postgres' " + ;
"port=5432" )
IF PQstatus( conn ) != CONNECTION_OK
? "Erro ao conectar na database final"
? PQerrorMessage( conn )
RETURN
ENDIF
? "Conectado na database:", cDB
/* 4. Menu simples */
DO WHILE cOpc != "0"
// CLS
? "Gerenciador de Banco de Dados"
? "1 - Inicializar tabelas"
? "2 - Inserir registro (exemplo)"
? "3 - Editar registro (exemplo)"
? "4 - Listar registros (exemplo)"
? "5 - Excluir registro (exemplo)"
? "6 - Selecionar registro (exemplo)"
? "0 - Sair"
?
cOpc := Chr( Inkey(0) )
DO CASE
CASE cOpc == "1"
StartDatabase( conn )
? "Tabelas verificadas/criadas."
Inkey(2)
CASE cOpc == "2"
hDados := {=>}
hDados["PAInCod"] := 77
hDados["PAInContin"] := 1
hDados["PAIcNome"] := "Brasil2"
hDados["PAIcCodNfe"] := "1059"
hDados["PAIcSigla"] := "BR"
nID := DbInsert( conn, "paises", hDados )
IF nID != NIL
? "Registro inserido/atualizado com ID:", nID
ELSE
? "Erro ao salvar registro."
ENDIF
Inkey(2)
CASE cOpc == "3"
hDados := {=>}
hDados["PAIcSigla"] := "BR3"
hDados["PAIcNome"] := "Brasil4"
nID := DbUpdate( conn, "paises", 2, hDados )
IF nID != NIL
? "Registro inserido/atualizado com ID:", nID
ELSE
? "Erro ao salvar registro."
ENDIF
Inkey(2)
CASE cOpc == "4"
//DbList( conn, cTabela, hFiltros, hOrder, nPagina, nPorPagina )
// aPaises := DbList( conn, "Paises" )
aPaises := DbList( conn, "Paises", { "is_active" => "TRUE" } , { "id" => "DESC" })
// aPaises := DbList( conn, "Paises", { "PAIcSigla" => "BR" } , { "id" => "DESC" })
// aPaises := DbList( conn, "Paises", NIL, { "id" => "DESC" } )
// aPaises := DbList( conn, "Paises", {"PAIcNome" => "Brasil4", "PAIcSigla" => "BR3"}, { "id" => "DESC" } )
// aPaises := DbList( conn, "Paises", { "PAIcSigla" => "BR" }, { "id" => "DESC" } )
// aPaises := DbSelect( conn, "SELECT * FROM paises", {} )
// aPaises := DbSelect( conn, "SELECT id::text, paincod::text, paincontin::text, paicnome, paiccodnfe, paicsigla FROM Paises WHERE id = $1", { "2" } )
? "Lista de paises:", hb_JsonEncode( aPaises , 4)
FOR i := 1 TO Len( aPaises )
? "ID:", aPaises[i]["id"], ;
"Nome:", aPaises[i]["paicnome"], ;
"Sigla:", aPaises[i]["paicsigla"]
NEXT
Inkey(4)
CASE cOpc == "5"
IF SqlDelete( conn, "paises", 3, .T. )
? "Registro excluído com sucesso."
ELSE
? "Erro ao excluir registro."
ENDIF
Inkey(2)
CASE cOpc == "6"
aPaises := DbSelect( conn, ;
"SELECT * FROM paises WHERE paicsigla = $1", ;
{ "BR3" } )
? "Registro selecionado:", hb_JsonEncode( aPaises , 4)
Inkey(2)
ENDCASE
ENDDO
RETURN
/* ========================================================= */
FUNCTION StartDatabase( conn )
LOCAL aCampos, aTabelas, i
LOCAL cNomeTabela
aTabelas := { ;
{"Pai", "Paises", "Lista de Países"}, ;
{"Ufs", "Estados", "Estados Brasileiros"}, ;
{"Mun", "Municipi", "Municípios Brasileiros"} }
FOR i := 1 TO Len( aTabelas )
cNomeTabela := aTabelas[i][2]
? "Criando tabela:", cNomeTabela
aCampos := ObterCampos( cNomeTabela )
CriarTabelaDinamica( conn, cNomeTabela, aCampos )
NEXT
RETURN NIL
/* ========================================================= */
FUNCTION ObterCampos( cNomeTabela )
LOCAL aCampos := {}
DO CASE
CASE cNomeTabela == "Paises"
aCampos := { ;
{"PAInCod","N",4,0}, ;
{"PAInContin","N",1,0}, ;
{"PAIcNome","C",35,0}, ;
{"PAIcCodNfe","C",4,0}, ;
{"PAIcSigla","C",3,0} }
CASE cNomeTabela == "Estados"
aCampos := { ;
{"UFScCod","C",4,0}, ;
{"UFScUf","C",2,0}, ;
{"UFScRegiao","C",12,0}, ;
{"UFScNome","C",25,0}, ;
{"CPF_CNPJ","C",14,0}, ;
{"UFSnIcm","N",6,2}, ;
{"UFSnFunPob","N",7,2}, ;
{"UFScConfig","C",5,0}, ;
{"UFScInsSub","C",14,0} }
CASE cNomeTabela == "Municipi"
aCampos := { ;
{"UFScUf","C",2,0}, ;
{"MUNcRegiao","C",10,0}, ;
{"MUNcCod","C",7,0}, ;
{"MUNcNome","C",25,0}, ;
{"CPF_CNPJ","C",14,0}, ;
{"MUNnTxLoc","N",8,2} }
ENDCASE
RETURN aCampos
/* ========================================================= */
FUNCTION CriarTabelaDinamica( conn, cTabela, aCampos )
LOCAL cSQL := "", i, res
IF Empty( aCampos )
RETURN NIL
ENDIF
cSQL := "CREATE TABLE IF NOT EXISTS " + cTabela + " ("
cSQL += "id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,"
FOR i := 1 TO Len( aCampos )
cSQL += CampoParaSQL( aCampos[i] )
IF i < Len( aCampos )
cSQL += ", "
ENDIF
NEXT
cSQL += ")"
res := PQexec( conn, cSQL )
IF PQresultStatus( res ) != PGRES_COMMAND_OK
? "Erro criando tabela:", cTabela
? PQerrorMessage( conn )
ENDIF
RETURN NIL
/* ========================================================= */
FUNCTION CampoParaSQL( aCampo )
LOCAL cNome := aCampo[1]
LOCAL cTipo := aCampo[2]
LOCAL nTam := aCampo[3]
LOCAL nDec := aCampo[4]
LOCAL cSQL
DO CASE
CASE cTipo == "C"
cSQL := cNome + " VARCHAR(" + LTrim(Str(nTam)) + ")"
CASE cTipo == "N"
IF nDec > 0
cSQL := cNome + " NUMERIC(" + ;
LTrim(Str(nTam)) + "," + ;
LTrim(Str(nDec)) + ")"
ELSE
IF nTam <= 9
cSQL := cNome + " INTEGER"
ELSE
cSQL := cNome + " BIGINT"
ENDIF
ENDIF
OTHERWISE
cSQL := cNome + " TEXT"
ENDCASE
RETURN cSQL
/* ========================================================= */
FUNCTION DbSelect( conn, cSQL, aParams )
/* Retorna uma lista de registros da tabela */
/*
aPaises := DbSelect( conn, ;
"SELECT * FROM paises WHERE sigla = $1", ;
{ "BR" } )
aPaises := DbSelect( conn, ;
"SELECT * FROM paises WHERE id = $1", ;
{ hb_ntos( nID ) } )
aDados := DbSelect( conn, ;
"SELECT * FROM estados WHERE uf = $1 AND regiao = $2", ;
{ "SP", "SUDESTE" } )
aDados := DbSelect( conn, ;
"SELECT * FROM municipios WHERE nome ILIKE $1", ;
{ "%" + cBusca + "%" } )
aDados := DbSelect( conn, ;
"SELECT * FROM produtos WHERE preco BETWEEN $1 AND $2", ;
{ hb_ntos( nMin ), hb_ntos( nMax ) } )
aDados := DbSelect( conn, ;
"SELECT * FROM estados WHERE uf = ANY($1)", ;
{ "{SP,RJ,MG}" } )
DbSelect( conn, "SELECT * FROM clientes WHERE cpf IS NULL" )
*/
LOCAL res, aRet := {}, n, hRow
res := IIF( Len( aParams ) > 0, ;
PQexecParams( conn, cSQL, aParams ), ;
PQexec( conn, cSQL ) )
IF PQresultStatus( res ) != PGRES_TUPLES_OK
? "Erro SQL:"
? PQresultErrorMessage( res )
RETURN aRet
ENDIF
FOR n := 1 TO PQntuples( res )
AAdd( aRet, DbRow( res, n ) )
NEXT
RETURN aRet
/* ========================================================= */
FUNCTION SqlFilter( conn, cTabela, hFiltro )
/* Retorna uma lista de registros da tabela filtrando por hFiltro */
/*Exemplo:
hFiltro := {=>}
hFiltro["uf"] := "SP"
hFiltro["regiao"] := "SUDESTE"
hFiltro["ativo"] := 1
aDados := SqlFilter( conn, "estados", hFiltro )
E por baixo vira:
SELECT * FROM estados
WHERE uf = $1 AND regiao = $2 AND ativo = $3
*/
LOCAL cSQL := "SELECT * FROM " + cTabela + " WHERE 1=1"
LOCAL aParams := {}
LOCAL cCampo, xValor
FOR EACH cCampo IN hFiltro
xValor := hFiltro[ cCampo ]
IF xValor == NIL
LOOP
ENDIF
cSQL += " AND " + cCampo + " = $" + hb_ntos( Len( aParams ) + 1 )
IF ValType( xValor ) == "N"
AAdd( aParams, hb_ntos( xValor ) )
ELSE
AAdd( aParams, xValor )
ENDIF
NEXT
RETURN DbSelect( conn, cSQL, aParams )
/* ========================================================= */
FUNCTION DbRow( res, nLinha )
LOCAL hRow := { => }
LOCAL i, cCampo
FOR i := 1 TO PQnfields( res )
cCampo := Lower( PQfname( res, i ) )
hRow[ cCampo ] := PQgetvalue( res, nLinha, i )
NEXT
RETURN hRow
/* ========================================================= */
FUNCTION DbInsert( conn, cTabela, hDados )
/* Retorna o ID do registro inserido */
/*
Exemplos:
h := {=>}
h["nome"] := "Produto A"
h["preco"] := 19.90
h["ativo"] := 1
nID := DbInsert( conn, "produtos", h )
*/
LOCAL aCampos := {}
LOCAL aValores := {}
LOCAL aParams := {}
LOCAL cCampo, xValor
LOCAL cSQL, res, nID
// ? "DADOS: ", hb_JsonEncode(hDados)
FOR EACH cCampo IN hb_HKeys( hDados )
// ? cCampo, "=", hDados[ cCampo ]
AAdd( aCampos, cCampo )
AAdd( aValores, "$" + hb_ntos( Len( aParams ) + 1 ) )
xValor := hDados[ cCampo ]
AAdd( aParams, IIF( ValType(xValor)=="N", hb_ntos(xValor), xValor ) )
NEXT
? "JsonValores: ", hb_JsonEncode(aValores)
? 'ArrayToSQL: ', ArrayToSQL( aValores, "," )
? 'Valores: ', ValType( ArrayToSQL( aValores, "," ) )
? 'Resultado: ', " VALUES (" + ArrayToSQL( aValores, "," ) + ")"
cSQL := ;
"INSERT INTO " + AllTrim( cTabela ) + ;
" (" + ArrayToSQL(aCampos, ",") + ")" + ;
" VALUES (" + Alltrim(ArrayToSQL( aValores, "," )) + ")" + ;
" RETURNING id"
? "SQL:", cSQL
res := PQexecParams( conn, cSQL, aParams )
IF PQresultStatus( res ) != PGRES_TUPLES_OK
? "Erro INSERT:", PQresultErrorMessage( res )
RETURN NIL
ENDIF
nID := Val( PQgetvalue( res, 1, 1 ) )
RETURN nID
/* ========================================================= */
FUNCTION DbUpdate( conn, cTabela, nID, hDados )
/*
Exemplos:
h := {=>}
h["nome"] := "Produto A+"
h["preco"] := 24.90
DbUpdate( conn, "produtos", 10, h )
*/
/* Atualiza apenas os campos que foram passados */
LOCAL aSet := {}
LOCAL aParams := {}
LOCAL cCampo, xValor
LOCAL cSQL, res
FOR EACH cCampo IN hb_HKeys( hDados )
IF Lower( cCampo ) == "id"
LOOP
ENDIF
AAdd( aSet, cCampo + " = $" + hb_ntos( Len( aParams ) + 1 ) )
xValor := hDados[ cCampo ]
AAdd( aParams, IIF( ValType(xValor)=="N", hb_ntos(xValor), xValor ) )
NEXT
/* ID entra por último */
AAdd( aParams, hb_ntos( nID ) )
cSQL := ;
"UPDATE " + AllTrim( cTabela ) + ;
" SET " + ArrayToSQL(aSet, ",") + ;
" WHERE id = $" + hb_ntos( Len( aParams ) )
res := PQexecParams( conn, cSQL, aParams )
IF PQresultStatus( res ) != PGRES_COMMAND_OK
? "Erro UPDATE:", PQresultErrorMessage( res )
RETURN .F.
ENDIF
RETURN .T.
/* ========================================================= */
FUNCTION SqlDelete( conn, cTabela, nID, lHardDelete )
/* Exemplo:
SqlDelete( conn, "produtos", 10 ) Não exclui o registro
SqlDelete( conn, "produtos", 10, .T. ) Exclui o registro
SELECT * FROM usuarios WHERE ativo = FALSE;
SELECT * FROM usuarios WHERE NOT ativo;
*/
LOCAL cSQL, res
lHardDelete := IIF( !( lHardDelete ), lHardDelete, .F. )
IF lHardDelete
cSQL := ;
"DELETE FROM " + cTabela + ;
" WHERE id = $1"
ELSE
cSQL := ;
"UPDATE " + cTabela + ;
" SET is_active = FALSE" + ;
" WHERE id = $1"
ENDIF
res := PQexecParams( conn, cSQL, { hb_ntos( nID ) } )
IF PQresultStatus( res ) != PGRES_COMMAND_OK
? "Erro DELETE:", PQresultErrorMessage( res )
RETURN .F.
ENDIF
RETURN .T.
/* ========================================================= */
FUNCTION DbSave( conn, cTabela, hDados )
/*
Salva um registro na tabela,
retornando o ID do registro inserido/atualizado
Exemplo:
hCliente := {=>}
hCliente["nome"] := "Otma"
hCliente["ativo"] := 1
SqlBegin( conn )
IF ! DbSave( conn, "clientes", hCliente )
SqlRollback( conn )
RETURN
ENDIF
SqlCommit( conn )
-----------------------------------------
h := {=>}
h["nome"] := "Brasil"
h["ativo"] := 1
DbBegin( conn )
nID := DbSave( conn, "paises", h )
IF nID == NIL
DbRollback( conn )
? "Erro ao salvar"
ELSE
DbCommit( conn )
? "Salvo com ID:", nID
ENDIF
-------------------------------------------
h := {=>}
h["id"] := 5
h["nome"] := "Brasil Atualizado"
DbSave( conn, "paises", h )
*/
LOCAL nID := 0
IF hb_HHasKey( hDados, "id" )
nID := Val( hDados["id"] )
ENDIF
IF nID <= 0
nID := DbInsert( conn, cTabela, hDados )
IF nID == NIL
RETURN NIL
ENDIF
hDados["id"] := nID
ELSE
IF ! DbUpdate( conn, cTabela, nID, hDados )
RETURN NIL
ENDIF
ENDIF
RETURN nID
/* ========================================================= */
FUNCTION SqlBegin( conn )
PQexec( conn, "BEGIN" )
RETURN NIL
/* ========================================================= */
FUNCTION SqlCommit( conn )
PQexec( conn, "COMMIT" )
RETURN NIL
/* ========================================================= */
FUNCTION SqlRollback( conn )
PQexec( conn, "ROLLBACK" )
RETURN NIL
/* ========================================================= */
FUNCTION DbSelectArray( conn, cSQL, hCampos, aParams )
/* Retorna um array de arrays com os dados da tabela */
/* Exemplo:
cSQL := "SELECT id, nome FROM paises WHERE ativo = 1"
hCampos := DbGetCamposTabela( conn, "paises" )
LOCAL cJSON := DbSelectArray( conn, cSQL, hCampos, aParams )
? cJSON
*/
LOCAL res, nLin, nCol, i, j
LOCAL aRows := {}
LOCAL hRow, cCampo, cTipo, xValor
res := PQexecParams( conn, cSQL, aParams )
IF PQresultStatus( res ) != PGRES_TUPLES_OK
? "Erro SELECT:", PQresultErrorMessage( res )
RETURN {}
ENDIF
nLin := PQntuples( res )
nCol := PQnfields( res )
FOR i := 1 TO nLin
hRow := {=>}
FOR j := 1 TO nCol
cCampo := PQfname( res, j )
xValor := PQgetvalue( res, i, j)
cTipo := hCampos[ cCampo ]
hRow[ cCampo ] := DbResolveCampo( xValor, cTipo )
NEXT
AAdd( aRows, hRow )
NEXT
RETURN aRows
/* ========================================================= */
FUNCTION DbSelectJSON( conn, cSQL, aParams )
/* Retorna os dados em formato JSON */
/* Exemplo:
cSQL := "SELECT id, nome FROM paises WHERE ativo = 1"
cJSON := DbSelectJSON( conn, cSQL )
? cJSON
*/
LOCAL aDados := DbSelectArray( conn, cSQL, aParams )
RETURN hb_jsonEncode( aDados )
/* ========================================================= */
FUNCTION ArrayToSQL( aArray, cSep )
LOCAL cOut := ""
LOCAL i
FOR i := 1 TO Len( aArray )
cOut += aArray[i]
IF i < Len( aArray )
cOut += cSep
ENDIF
NEXT
RETURN cOut
/* ========================================================= */
FUNCTION DbList( conn, cTabela, hFiltros, hOrder, nPagina, nPorPagina )
LOCAL cSQL, aParams := {}
LOCAL cWhere := " WHERE 1=1 "
LOCAL aPag, nLim, nOff
LOCAL cCampo, xValor, i
LOCAL cCamposCorrigidos := "*"
LOCAL hCampos := {}
LOCAL aKeys := {}
IF Empty( hOrder )
hOrder := { "id" => "ASC" }
ENDIF
hCampos := DbGetCamposTabela( conn, cTabela )
// ? "Campos da tabela: ", hb_JsonEncode( hCampos, 4 )
IF !Empty( hFiltros )
FOR EACH cCampo IN hb_HKeys( hFiltros )
xValor := hFiltros[ cCampo ]
IF !Empty( xValor )
cWhere += ;
" AND " + cCampo + ;
" = $" + LTrim(Str(Len(aParams)+1))
AAdd( aParams, hb_ValToStr( xValor ) )
ENDIF
NEXT
aKeys := hb_HKeys( hCampos )
nLen := Len( aKeys )
cCamposCorrigidos := ""
FOR i := 1 TO nLen
cCampo := aKeys[i]
IF "int" $ Lower( hCampos[cCampo] ) .OR. "float" $ Lower( hCampos[cCampo] )
cCamposCorrigidos += cCampo + "::text AS " + cCampo
ELSE
cCamposCorrigidos += cCampo
ENDIF
// Adiciona a vírgula apenas se NÃO for o último elemento
IF i < nLen
cCamposCorrigidos += ", "
ENDIF
NEXT
ENDIF
cOrder := DbBuildOrderBy( hOrder, hCampos )
cSQL := ;
"SELECT " + cCamposCorrigidos + " FROM " + cTabela + ;
cWhere + ;
cOrder
IF !Empty( nPagina ) .AND. !Empty( nPorPagina )
aPag := DbPaginate( nPagina, nPorPagina )
nLim := aPag[1]
nOff := aPag[2]
cSQL += " LIMIT " + LTrim( Str( nLim ) ) + ;
" OFFSET " + LTrim( Str( nOff ) )
ENDIF
? "SQL FINAL: ", cSQL
? "Parametros: ", hb_JsonEncode( aParams )
?
RETURN DbSelectArray( conn, cSQL, hCampos, aParams )
/* ========================================================= */
FUNCTION DbBuildOrderBy( hOrder, hCampos )
LOCAL cSQL := ""
LOCAL cCampo, cDir
LOCAL aParts := {}
IF Empty( hOrder )
RETURN ""
ENDIF
FOR EACH cCampo IN hb_HKeys( hOrder )
cDir := hOrder[ cCampo ]
? "Ordenando por:", cCampo, cDir
/* valida direção */
cDir := Upper( cDir )
IF cDir != "ASC" .AND. cDir != "DESC"
cDir := "ASC"
ENDIF
AAdd( aParts, cCampo + " " + cDir )
NEXT
? "Parts:", Len( aParts )
? "Parts:", ArrayToSQL( aParts )
IF Len( aParts ) > 0
cSQL := " ORDER BY " + ArrayToSQL( aParts )
ENDIF
RETURN cSQL
/* ========================================================= */
FUNCTION DbPaginate( nPagina, nPorPagina )
LOCAL nOffset
IF nPagina == NIL
nPagina := 1
ENDIF
IF nPorPagina == NIL
nPorPagina := 20
ENDIF
IF nPagina < 1
nPagina := 1
ENDIF
nOffset := ( nPagina - 1 ) * nPorPagina
RETURN { nPorPagina, nOffset }
/* ========================================================= */
FUNCTION DbGetCamposTabela( conn, cTabela )
STATIC hCache := {=>}
LOCAL cKey := Lower( cTabela )
LOCAL cSQL, res, i
LOCAL cCampo, cTipo
IF HB_HHasKey( hCache, cKey )
RETURN hCache[ cKey ]
ENDIF
cSQL := ;
"SELECT column_name, data_type " + ;
"FROM information_schema.columns " + ;
"WHERE table_schema = 'public' " + ;
"AND table_name = $1 " + ;
"ORDER BY ordinal_position"
res := PQexecParams( conn, cSQL, { cKey } )
IF PQresultStatus( res ) != PGRES_TUPLES_OK
? "Erro lendo campos da tabela:", cTabela
? PQerrorMessage( conn )
RETURN {}
ENDIF
hCache[ cKey ] := {=>}
FOR i := 1 TO PQntuples( res )
cCampo := Lower( PQgetvalue( res, i, 1 ) )
cTipo := PQgetvalue( res, i, 2 )
hCache[ cKey ][ cCampo ] := cTipo
NEXT
RETURN hCache[ cKey ]
/* ========================================================= */
FUNCTION DbResolveCampo( cValor, cTipo )
DO CASE
CASE cTipo == "integer" .OR. cTipo == "bigint"
RETURN Val( cValor )
CASE cTipo == "numeric"
RETURN Val( StrTran( cValor, ",", "." ) )
CASE cTipo == "boolean"
? "Valor booleano:", Asc( cValor )
RETURN ( Asc( cValor ) == 1 )
CASE cTipo == "date"
RETURN cValor // ou converter depois
OTHERWISE
IF Empty( cValor )
RETURN NIL
ENDIF
RETURN cValor
ENDCASE
RETURN NIL