On-line: гостей 2. Всего: 2 [подробнее..]
АвторСообщение
moderator




Пост N: 2201
Зарегистрирован: 11.02.10
ссылка на сообщение  Отправлено: 13.10.23 16:46. Заголовок: Библиотека SQLRDD для Харбора


Всем кому это интересно
Стали доступны исходники известной библиотеки SQLRDD для xXарбора, которая раньше была платной.
Сейчас адаптирую для работы с Минигуи эту библиотеку, которая позволяет портировать синтаксис Харбора без всяких изменений для работы с серверами MySQL, Postgres, Firebird, Oracle, MS SQL.

Подготовил для сравнения две программы - одна использует SQLRDD для доступа к таблице на сервере MySQL, а другая использует для доступа к DBF драйвер DBFCDX.

Код первой программы ниже
 
#include "minigui.ch"
#include "sqlrdd.ch"

REQUEST SQLRDD
REQUEST SR_MYSQL


// NOTE: the database must exist before runnning the test.
#define SERVER "localhost"
#define UID "root"
#define PWD "mypass"
#define DTB "test"

*--------------------------------------------------------*
FUNCTION Main()
*--------------------------------------------------------*

LOCAL nConnection

rddSetDefault( "SQLRDD" )

nConnection := sr_AddConnection( CONNECT_MYSQL, "MySQL=" + SERVER + ";UID=" + UID + ";PWD=" + PWD + ";DTB=" + DTB )

IF nConnection < 0
Alert( "Connection error. See sqlerror.log for details." )
RETURN NIL
ELSE
//Alert( "Connected to : " + SR_GetConnectionInfo(, SQL_DBMS_NAME ) + " " + SR_GetConnectionInfo(, SQL_DBMS_VER ) )
ENDIF

DEFINE WINDOW Form_1 ;
WIDTH 640 HEIGHT 480 ;
TITLE 'SQLRDD Demo' ;
MAIN NOMAXIMIZE ;
ON INIT OpenTable() ;
ON RELEASE CloseTable()

DEFINE MAIN MENU

DEFINE POPUP 'Test'
MENUITEM 'Add record' ACTION AddRecord( 'ARG', 'Argentina', 38740000 )
SEPARATOR
ITEM "Exit" ACTION ThisWindow.Release()
END POPUP

END MENU

@ 10, 10 BROWSE Browse_1 ;
WIDTH 610 ;
HEIGHT 390 ;
HEADERS { 'Code', 'Name', 'Residents' } ;
WIDTHS { 50, 160, 100 } ;
WORKAREA country ;
FIELDS { 'Code', 'Name', 'Residents' } ;
JUSTIFY { BROWSE_JTFY_LEFT, BROWSE_JTFY_LEFT, BROWSE_JTFY_RIGHT } ;
EDIT ;
INPLACE ;
READONLY { .T., .F., .F. }

END WINDOW

CENTER WINDOW Form_1

ACTIVATE WINDOW Form_1

RETURN NIL

*--------------------------------------------------------*
PROCEDURE OpenTable
*--------------------------------------------------------*

Form_1.Browse_1.VISIBLE := .F.

CreateTable()

INDEX ON FIELD->RESIDENTS TAG residents TO country

GO TOP

Form_1.Browse_1.VISIBLE := .T.

RETURN

*--------------------------------------------------------*
PROCEDURE CloseTable
*--------------------------------------------------------*

dbCloseArea( "country" )

RETURN

*--------------------------------------------------------*
FUNCTION CreateTable
*--------------------------------------------------------*

LOCAL aStruct := { ;
{ "CODE", "C", 3, 0 }, ;
{ "NAME", "C", 50, 0 }, ;
{ "RESIDENTS", "N", 11, 0 } ;
}

IF sr_file( "country" )
sr_DropTable( "country" )
sr_DropIndex( "country" )
ENDIF

dbCreate( "country", aStruct, "SQLRDD" )

USE country /*EXCLUSIVE*/ VIA "SQLRDD"

dbAppend()
REPLACE CODE WITH 'LTU', NAME WITH 'Lithuania', RESIDENTS WITH 3369600
dbAppend()
REPLACE CODE WITH 'USA', NAME WITH 'United States of America', RESIDENTS WITH 305397000
dbAppend()
REPLACE CODE WITH 'POR', NAME WITH 'Portugal', RESIDENTS WITH 10617600
dbAppend()
REPLACE CODE WITH 'POL', NAME WITH 'Poland', RESIDENTS WITH 38115967
dbAppend()
REPLACE CODE WITH 'AUS', NAME WITH 'Australia', RESIDENTS WITH 21446187
dbAppend()
REPLACE CODE WITH 'FRA', NAME WITH 'France', RESIDENTS WITH 64473140
dbAppend()
REPLACE CODE WITH 'RUS', NAME WITH 'Russia', RESIDENTS WITH 141900000

RETURN NIL

*--------------------------------------------------------*
PROCEDURE AddRecord( cCode, cName, nResidents )
*--------------------------------------------------------*

APPEND BLANK

REPLACE CODE WITH cCode, ;
NAME WITH cName, ;
RESIDENTS WITH nResidents

dbUnlock() // Recno() is valid only after UNLOCK or COMMIT

Form_1.Browse_1.VALUE := country->( RecNo() )
Form_1.Browse_1.Refresh

RETURN

и для сравнения код второй программы:
#include "minigui.ch" 

REQUEST DBFCDX

*--------------------------------------------------------*
FUNCTION Main()
*--------------------------------------------------------*

rddSetDefault( "DBFCDX" )

DEFINE WINDOW Form_1 ;
WIDTH 640 HEIGHT 480 ;
TITLE 'DBFCDX Demo' ;
MAIN NOMAXIMIZE ;
ON INIT OpenTable() ;
ON RELEASE CloseTable()

DEFINE MAIN MENU

DEFINE POPUP 'Test'
MENUITEM 'Add record' ACTION AddRecord( 'ARG', 'Argentina', 38740000 )
SEPARATOR
ITEM "Exit" ACTION ThisWindow.Release()
END POPUP

END MENU

@ 10, 10 BROWSE Browse_1 ;
WIDTH 610 ;
HEIGHT 390 ;
HEADERS { 'Code', 'Name', 'Residents' } ;
WIDTHS { 50, 160, 100 } ;
WORKAREA country ;
FIELDS { 'Code', 'Name', 'Residents' } ;
JUSTIFY { BROWSE_JTFY_LEFT, BROWSE_JTFY_LEFT, BROWSE_JTFY_RIGHT } ;
EDIT ;
INPLACE ;
READONLY { .T., .F., .F. }

END WINDOW

CENTER WINDOW Form_1

ACTIVATE WINDOW Form_1

RETURN NIL

*--------------------------------------------------------*
PROCEDURE OpenTable
*--------------------------------------------------------*

Form_1.Browse_1.VISIBLE := .F.

CreateTable()

INDEX ON FIELD->RESIDENTS TAG residents TO country

GO TOP

Form_1.Browse_1.VISIBLE := .T.

RETURN

*--------------------------------------------------------*
PROCEDURE CloseTable
*--------------------------------------------------------*

dbCloseArea( "country" )

RETURN

*--------------------------------------------------------*
FUNCTION CreateTable
*--------------------------------------------------------*

LOCAL aStruct := { ;
{ "CODE", "C", 3, 0 }, ;
{ "NAME", "C", 50, 0 }, ;
{ "RESIDENTS", "N", 11, 0 } ;
}

IF File( "country.dbf" )
FErase( "country.dbf" )
FErase( "country.cdx" )
ENDIF

dbCreate( "country", aStruct, "DBFCDX" )

USE country /*EXCLUSIVE*/ VIA "DBFCDX"

dbAppend()
REPLACE CODE WITH 'LTU', NAME WITH 'Lithuania', RESIDENTS WITH 3369600
dbAppend()
REPLACE CODE WITH 'USA', NAME WITH 'United States of America', RESIDENTS WITH 305397000
dbAppend()
REPLACE CODE WITH 'POR', NAME WITH 'Portugal', RESIDENTS WITH 10617600
dbAppend()
REPLACE CODE WITH 'POL', NAME WITH 'Poland', RESIDENTS WITH 38115967
dbAppend()
REPLACE CODE WITH 'AUS', NAME WITH 'Australia', RESIDENTS WITH 21446187
dbAppend()
REPLACE CODE WITH 'FRA', NAME WITH 'France', RESIDENTS WITH 64473140
dbAppend()
REPLACE CODE WITH 'RUS', NAME WITH 'Russia', RESIDENTS WITH 141900000

RETURN NIL

*--------------------------------------------------------*
PROCEDURE AddRecord( cCode, cName, nResidents )
*--------------------------------------------------------*

APPEND BLANK

REPLACE CODE WITH cCode, ;
NAME WITH cName, ;
RESIDENTS WITH nResidents

Form_1.Browse_1.VALUE := country->( RecNo() )
Form_1.Browse_1.Refresh

RETURN

Как Вы можете увидеть, различия у этих программ минимальные:
для SQLRDD нужно добавить только подключение к серверу MySQL.

Ваши комментарии на тему актуальности этой библиотеки приветствуются...

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 36 , стр: 1 2 All [только новые]


Администратор




Пост N: 4133
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 15.10.23 19:32. Заголовок: Там еще очень подроб..


Там еще очень подробная дока есть, в том числе по функциям. Проект же был коммерческий

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1962
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 15.10.23 19:37. Заголовок: gfilatov2002 пишет: ..


gfilatov2002 пишет:

 цитата:

Ваши комментарии на тему актуальности этой библиотеки приветствуются...


Григорий, какие могут быть комментарии, конечно расширение любого функционала всегда востребовано.
Я к базам MySQL через ODBC лезу, конечно интересно и другие варианты пощупать

Спасибо: 0 
ПрофильЦитата Ответить
moderator




Пост N: 2205
Зарегистрирован: 11.02.10
ссылка на сообщение  Отправлено: 15.10.23 21:11. Заголовок: Haz пишет: расширен..


Haz пишет:

 цитата:
расширение любого функционала всегда востребовано


Благодарю за комментарий
Дело в том, что мне также пришлось править код Минигуи, поскольку команда EDIT EXTENDED вылетала при выходе из просмотра таблицы, открытой с помощью SQLRDD

Спасибо: 0 
ПрофильЦитата Ответить
moderator




Пост N: 2206
Зарегистрирован: 11.02.10
ссылка на сообщение  Отправлено: 20.10.23 13:43. Заголовок: Всем кому это интересно


Еще один небольшой пример для тестирования SQLRDD, адаптированный для Минигуи:

/* 
* SQLRDD database info demo
* Copyright (c) 2008 - Marcelo Lombardo <lombardo@uol.com.br>
* All Rights Reserved
*/

#define _HMG_OUTLOG
#include <minigui.ch>
#include "sqlrdd.ch"
#include "dbinfo.ch"

#define RECORDS_IN_TEST 100
FIELD CODE_ID, DAYS

FUNCTION MAIN( cRdd, cDsn )

local aStruct := {{"CODE_ID","C",8,0 },{"CARDID","C",1,0},{"DESCR","C",50,0},{"PERCENT","N",8,2},{"DAYS","N",6,0},{"DATE_LIM","D",8,0},{"ENABLE","L",1,0},{"OBS","M",10,0}, {"VALUE","N",18,6}}

Local i

DEFAULT cRDD := "SQLRDD"

Connect( @cRDD, cDSN ) // see connect.prg

? "Connected to ", SR_GetConnectionInfo(, SQL_DBMS_NAME ), SR_GetConnectionInfo(, SQL_DBMS_VER )
? "Creating table"

dbCreate( "TEST_TABLE3", aStruct, cRDD )
USE TEST_TABLE3 via cRDD
INDEX ON CODE_ID TO TBL3_INDX
INDEX ON CODE_ID TAG CODE_ID FOR DAYS < 20

For i = 1 to RECORDS_IN_TEST
Append Blank
Replace CODE_ID with strZero( i, 5 )
Replace DESCR with dtoc( date() ) + " - " + time()
Replace DAYS with (RECORDS_IN_TEST - i)
Replace DATE_LIM with date()
Replace ENABLE with .T.
Replace OBS with "This is a memo field. Seconds since midnight : " + alltrim(str(seconds()))
Next

dbGoTop()

? "RDD Version :", dbInfo( DBI_RDD_VERSION )
? "RDD Build :", dbInfo( DBI_RDD_BUILD )

? "SR_FILE() :", sr_file( "TEST_TABLE3" )
? "FILE() :", file( "TEST_TABLE3" ) // There is no phisical file with such name, should return .F.
? "Standard table structure"
? sr_showVector( dbStruct() )

EDIT EXTENDED

DbCloseAll()
? "Drop Table :", SR_DropTable("TEST_TABLE3")

RETURN NIL

/*------------------------------------------------------------------------*/

#include "connect.prg"

/*------------------------------------------------------------------------*/

Вывод этой программы после запуска:
 
Connected to MYSQL NATIVE 80030
Creating table
RDD Version : MGMNT 1.72
RDD Build : 15
SR_FILE() : .T.
FILE() : .F.
Standard table structure
{{CODE_ID,C,8,0},
{CARDID,C,1,0},
{DESCR,C,50,0},
{PERCENT,N,8,2},
{DAYS,N,6,0},
{DATE_LIM,D,8,0},
{ENABLE,L,1,0},
{OBS,M,10,0},
{VALUE,N,18,6}
}
Drop Table : .T.


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 7844
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.10.23 15:42. Заголовок: gfilatov2002 пишет: ..


gfilatov2002 пишет:

 цитата:
Еще один небольшой пример для тестирования SQLRDD, адаптированный для Минигуи:


В консоли будет работать SQLRDD или надо допиливать ?

Спасибо: 0 
ПрофильЦитата Ответить
moderator




Пост N: 2207
Зарегистрирован: 11.02.10
ссылка на сообщение  Отправлено: 20.10.23 16:03. Заголовок: Dima пишет: В консо..


Dima пишет:

 цитата:
В консоли будет работать SQLRDD


Будет работать
Посмотри консольный пример для MySQL ниже:
 
// SQLRDD
// test with MySQL
// To compile:
// hbmk2 mysql2 -llibmysql

#include "sqlrdd.ch"
#include "inkey.ch"

// Make a copy of this file and change the values below.
// NOTE: the database must exist before runnning the test.
#define SERVER "localhost"
#define UID "root"
#define PWD "password"
#define DTB "dbtest"

REQUEST SQLRDD
REQUEST SQLEX
REQUEST SR_MYSQL

PROCEDURE Main()

LOCAL nConnection
LOCAL n
LOCAL oTB
LOCAL nKey

setMode(25, 80)

rddSetDefault("SQLRDD")

nConnection := sr_AddConnection(CONNECT_MYSQL, "MySQL=" + SERVER + ";UID=" + UID + ";PWD=" + PWD + ";DTB=" + DTB)

IF nConnection < 0
alert("Connection error. See sqlerror.log for details.")
QUIT
ENDIF

sr_StartLog(nConnection)

IF !sr_ExistTable("test")
dbCreate("test", {{"ID", "N", 10, 0}, ;
{"FIRST", "C", 30, 0}, ;
{"LAST", "C", 30, 0}, ;
{"AGE", "N", 3, 0}, ;
{"DATE", "D", 8, 0}, ;
{"MARRIED", "L", 1, 0}, ;
{"VALUE", "N", 12, 2}}, "SQLRDD")
ENDIF

USE test EXCLUSIVE VIA "SQLRDD"

IF reccount() < 100
FOR n := 1 TO 100
APPEND BLANK
REPLACE ID WITH n
REPLACE FIRST WITH "FIRST" + hb_ntos(n)
REPLACE LAST WITH "LAST" + hb_ntos(n)
REPLACE AGE WITH n + 18
REPLACE DATE WITH date() - n
REPLACE MARRIED WITH iif(n / 2 == int(n / 2), .T., .F.)
REPLACE VALUE WITH n * 1000 / 100
NEXT n
ENDIF

GO TOP

oTB := TBrowseDB(0, 0, maxrow(), maxcol())

oTB:addColumn(TBColumnNew("ID", {||TEST->ID}))
oTB:addColumn(TBColumnNew("FIRST", {||TEST->FIRST}))
oTB:addColumn(TBColumnNew("LAST", {||TEST->LAST}))
oTB:addColumn(TBColumnNew("AGE", {||TEST->AGE}))
oTB:addColumn(TBColumnNew("DATE", {||TEST->DATE}))
oTB:addColumn(TBColumnNew("MARRIED", {||TEST->MARRIED}))
oTB:addColumn(TBColumnNew("VALUE", {||TEST->VALUE}))

DO WHILE nKey != K_ESC
dispbegin()
DO WHILE !oTB:stabilize()
ENDDO
dispend()
nKey := inkey(0)
SWITCH nKey
CASE K_UP
oTB:up()
EXIT
CASE K_DOWN
oTB:down()
EXIT
CASE K_LEFT
oTB:left()
EXIT
CASE K_RIGHT
oTB:right()
EXIT
CASE K_PGUP
oTB:PageUp()
EXIT
CASE K_PGDN
oTB:PageDown()
ENDSWITCH
ENDDO

CLOSE DATABASE

sr_StopLog(nConnection)

sr_EndConnection(nConnection)

RETURN


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 7845
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.10.23 16:07. Заголовок: gfilatov2002 пишет: ..


gfilatov2002 пишет:

 цитата:
Будет работать




Спасибо: 0 
ПрофильЦитата Ответить
moderator




Пост N: 2208
Зарегистрирован: 11.02.10
ссылка на сообщение  Отправлено: 22.10.23 18:31. Заголовок: Всем кому это интересно


Попробовал переписать пример MySqlCli с использованием библиотеки SQLRDD.

На картинке ниже можно увидеть результат работы этой программы:



Спасибо: 0 
ПрофильЦитата Ответить
moderator




Пост N: 2209
Зарегистрирован: 11.02.10
ссылка на сообщение  Отправлено: 23.10.23 19:40. Заголовок: gfilatov2002 пишет: ..


gfilatov2002 пишет:

 цитата:
пример MySqlCli с использованием библиотеки SQLRDD


Если у кого-либо есть желание попробовать этот пример вживую, то я выложил его здесь.
Для проверки потребуется тестовый сервер MySQL, который можно скачать с его официального сайта
http://dev.mysql.com/downloads/
Заранее благодарю за отзывы

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 4436
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 23.10.23 21:38. Заголовок: gfilatov2002 пишет Д..


gfilatov2002 пишет
 цитата:
Для проверки потребуется тестовый сервер MySQL, который можно скачать с его официального сайта


Правильно понимаю, ставим сервер версии 8.0.4, а пример будет использовать dll версии от 2010 года ?
Очень давно не сталкивался с mysql, забылось многое. В VO для работы бралась клиентская dll из сервера той же версии

Спасибо: 0 
ПрофильЦитата Ответить
moderator




Пост N: 2210
Зарегистрирован: 11.02.10
ссылка на сообщение  Отправлено: 24.10.23 10:02. Заголовок: SergKis пишет: став..


SergKis пишет:

 цитата:
ставим сервер версии 8.0.4, а пример будет использовать dll версии от 2010 года


Да, все правильно
SergKis пишет:

 цитата:
для работы бралась клиентская dll из сервера той же версии


Можно и так. Но тогда потребуется пересобрать под эту dll соответствующую ей библиотеку libmysql.lib.
Я так делаю для 64-битной MinGW-версии.

P.S. Обращаю внимание, что SQLRDD будет создавать свои служебные таблицы в каждой базе данных, к которой будет обращаться программа. Поэтому я и рекомендовал создать пробный MySQL сервер для проверки библиотеки SQLRDD.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 4437
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 24.10.23 14:01. Заголовок: gfilatov2002 пишет S..


gfilatov2002 пишет
 цитата:
SQLRDD будет создавать свои служебные таблицы в каждой базе данных, к которой будет обращаться программа.


Для чужого сервера это так же будет проделываться ? Не уверен, что админ разрешит это проделывать.

Спасибо: 0 
ПрофильЦитата Ответить
moderator




Пост N: 2211
Зарегистрирован: 11.02.10
ссылка на сообщение  Отправлено: 24.10.23 14:08. Заголовок: SergKis пишет: Для ..


SergKis пишет:

 цитата:
Для чужого сервера это так же будет проделываться ?


Угу
SergKis пишет:

 цитата:
Не уверен, что админ разрешит это проделывать


Полностью с ним согласен.
Поэтому в обычном режиме программа должна работать только со своей базой MySQL, которую она сама создала.
Но mysqlcli может обращаться к любой базе, поэтому я и сделал заранее такое предупреждение о тестовом сервере...

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 4438
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 24.10.23 16:04. Заголовок: gfilatov2002 пишет П..


gfilatov2002 пишет
 цитата:
Поэтому в обычном режиме программа должна работать только со своей базой MySQL, которую она сама создала


Для FireBird, где из основной базы через gbak.exe получают копию ее и на др. сервере восстанавливают через нее, для дальнейшей информационной обработки, думаю SQLRDD должна подойти на все 100%. Интересно, как надо будет читать таблицу с ~10 000 000 записями ? Доступны ли описания и view из основной системы ? Или надо свои делать ?
PS
MySql с таблицами InnoDb убрали из работы оч. давно ~2004-2006 гг. (редко, но пропадали записи) ушел на FireBird, а потом на LetoDb

Спасибо: 0 
ПрофильЦитата Ответить
moderator




Пост N: 2212
Зарегистрирован: 11.02.10
ссылка на сообщение  Отправлено: 24.10.23 16:22. Заголовок: SergKis пишет: Или ..


SergKis пишет:

 цитата:
Или надо свои делать ?


Надо делать свои.
Кстати, для выборки можно использовать DBF - есть функция SR_SetRDDTemp().

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 143
Зарегистрирован: 24.04.13
ссылка на сообщение  Отправлено: 21.12.23 13:48. Заголовок: gfilatov2002 пишет: ..


gfilatov2002 пишет:

 цитата:
Будет работать
Посмотри консольный пример для MySQL ниже:


Что-то не собирается, libmysql.lib с гитхаба lib\bc5 ?

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 36 , стр: 1 2 All [только новые]
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 144
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет