Хранение изображения

alextashk
Дата: 17.03.2015 07:24:10
Добрый день!

Есть таблица
  	CREATE TABLE "d_picture"  
  	(  
  	id character(30) PRIMARY KEY,  
  	dtadd timestamp without time zone DEFAULT now(),  
  	dtizm timestamp without time zone DEFAULT now(),  
  	idparent character(30),   
  	cpath character(254),   
  	cpic bytea,   
  	copis character(50)  
  	)  
  	WITH (  
  		OIDS=TRUE  
  		);  
  	CREATE INDEX d_picture_parent ON "d_picture" (idparent); 


Пытаюсь загнать файл в поле cpic через VFP
 SCAN  
  	lcPath1 = '"' + gcPath + 'pictures\' + d_picture.idParent + '\' + ALLTRIM(d_picture.cPath1) + '"'  
  	IF FILE(lcPath1) THEN  
  		lcFile = CAST(FILETOSTR(lcPath1)  as BLOB)
  		TEXT TO lcSQL TEXTMERGE PRETEXT 15 NOSHOW  
  			INSERT INTO d_picture(id, dtadd, dtizm, idparent, cpath, cpic, copis)   
  				VALUES (?d_picture.id, ?d_picture.dtadd, ?d_picture.dtizm,  
  					?d_picture.idparent, ?d_picture.cpath, ?lcfile, ?d_picture.copis);  
  		ENDTEXT  
  		lnOk = my_SQL(lcSQL, '', .T., '')  
  	ENDIF  
  ENDSCAN  


PostgreSQL ругается, говорит, что нет типа lo

что делать?
alextashk
Дата: 17.03.2015 08:06:20
ошибка - 1526
тип lo не существует

postgresql 9.4 на windows
alextashk
Дата: 17.03.2015 09:19:10
тип lo добавил!

postgresql ругнулся на не соответствие типов lo и bytea

если в таблице поправить тип cPic с bytea на lo - файлы уходят на сервер, но как их оттуда вытащить?

SELECT id, lo_get(cPic) FROM d_picture WHERE id = '111'

Через SQLEXEC - отрабатывает без ошибок, но не создаёт таблицу на стороне VFP

в общем 2 вопроса:
1. Если хранить файлы на сервере в типе lo - как их вытащить?
2. Если хранить файлы на сервере в типе bytea - как их туда загнать
grufos
Дата: 17.03.2015 11:54:10
alextashk,

киньте пожалуйста ваш код подключения к PostgreSQL и чтения возвращаемого рекордсета
я хотел бы провести у себя эксперименты
alextashk
Дата: 17.03.2015 13:06:01
grufos,

gcConnect = "DRIVER={PostgreSQL ODBC Driver(ANSI)};" + ;  
	"SERVER=localhost;" + ;  
	"PORT=2222;" + ;  
	"UID=dd;" + ;  
	"PWD=dd;" + ;  
	"DATABASE=dd;" + ;
	"BOOLSASCHAR=0"
    
gnHandle = SQLSTRINGCONNECT( gcConnect)  


TEXT
   SELECT id, dtadd, dtizm, idparent, cpath, lo_get(cpic) as dd, copis
    FROM f_picture
     WHERE f_picture.id ='11' ;
ENDTEXT
  lnOk = my_SQL(lcSQL, 'll_dd', .T., '')
  SELECT ll_dd
  COPY TO d:\ff


FUNCTION my_SQL
LPARAMETERS tcText, tcAlias, tlError, tcError
WAIT WINDOW tcError NOWAIT
IF gnHandle < 1 THEN
	gnHandle = SQLSTRINGCONNECT(gcConnect)
	IF gnHandle < 1 THEN
	* &#206;&#225;&#240;&#224;&#225;&#238;&#242;&#234;&#224; &#238;&#248;&#232;&#225;&#234;&#232; &#239;&#238;&#228;&#234;&#235;&#254;&#247;&#229;&#237;&#232;&#255;
		lcConnect = gcConnect
		lnBeg = AT('UID=', lcConnect) + 2
		FOR lnPer = 1 TO 20
			IF lnBeg + lnPer < LEN(lcConnect) .AND. SUBSTR(lcConnect, lnBeg + lnPer, 1) THEN
				lcConnect = LEFT(lcConnect, lnBeg + lnPer) + 'X' + RIGHT(lcConnect, LEN(lcConnect) - lnBeg - lnPer - 1)
			ELSE
				EXIT
			ENDIF
		NEXT 
		lnBeg = AT('PWD=', lcConnect) + 2
		FOR lnPer = 1 TO 20
			IF lnBeg + lnPer < LEN(lcConnect) .AND. SUBSTR(lcConnect, lnBeg + lnPer, 1) THEN
				lcConnect = LEFT(lcConnect, lnBeg + lnPer) + 'X' + RIGHT(lcConnect, LEN(lcConnect) - lnBeg - lnPer - 1)
			ELSE
				EXIT
			ENDIF
		NEXT 
		lnOk = err_SQL('&#207;&#238;&#228;&#234;&#235;&#254;&#247;&#229;&#237;&#232;&#229;' + CHR(10) + CHR(13) + lcConnect, .T.)
	ENDIF
ENDIF
USE IN SELECT(tcAlias)
lnOk = SQLEXEC(gnHandle, tcText, tcAlias)
IF lnOk < 1 THEN
	lnOk = err_SQL(tcError + CHR(13) + CHR(10) + tcText, tlError)
ENDIF
WAIT CLEAR
RETURN lnOk
grufos
Дата: 17.03.2015 13:15:56
alextashk,
спасибо, разбираюсь...
grufos
Дата: 17.03.2015 13:50:58
alextashk,

в какой кодировке у вас БД?
Так как вы работаете с Foxpro, то могу предположить, что 'WIN1251'
я попробовал поработать с типом bytea
_lcConn = 'DRIVER={PostgreSQL ODBC Driver(ANSI)};DATABASE='+_lcBase+';SERVER='+_lcServer+';PORT=5432;Uid='+_lcUser+';'+';Pwd='+_lcPass+';B9=1;"'
_lnHandle = SQLSTRINGCONNECT(_lcConn)
IF _lnHandle < 0  && нет соединения с сервером

    * анализируем ошибку
	DO ErrHand with "Не удалось установить соединение с сервером."
	
    ON ERROR &_lcOldError			&& восстанавливаем обработчик ошибок
    RETURN .F.
ELSE   
	* есть соединение

    * устанавливаем свой обработчик ошибок
	ON ERROR DO ErrHand with ""
    * выполняемая команда на сервере
    _lcCommand = "insert into d_picture (id, cpath, cpic) values(1, 'c:\temp\picture\94.log','Тестовая строка');"
	SQLEXEC(_lnHandle, _lcCommand)

    _lcCommand = "select * from d_picture"
	SQLEXEC(_lnHandle, _lcCommand)
	
    SQLDISCONNECT(_lnHandle)				&& закрываем соединение
ENDIF

в итоге в курсоре SqlResult в Memo поле получил исходную строку.
У вас так работает?
grufos
Дата: 17.03.2015 14:12:15
alextashk,
вот так тоже получаю в результате исходный файл
    _lcFile = FILETOSTR('c:\temp\94.log')
    _lcCommand = "insert into d_picture (id, cpath, cpic) values(1, 'c:\temp\94.log',?_lcFile);"
	SQLEXEC(_lnHandle, _lcCommand)

    _lcCommand = "select * from d_picture"
	SQLEXEC(_lnHandle, _lcCommand)
alextashk
Дата: 17.03.2015 20:17:36
grufos,

Спасибо за интерес к теме.

У меня, с помощью более опытных товарищей (точнее слямзил решение у них)
1. Подключение
gcConnect = "DRIVER={PostgreSQL ODBC Driver(ANSI)};" + ;  
	"SERVER=localhost;" + ;  
	"PORT=dd;" + ;  
	"UID=dd;" + ;  
	"PWD=dd;" + ;  
	"DATABASE=dd;" + ;
	"BOOLSASCHAR=0;" + ;
	"[b]C7=1[/b]"


2.Закачка на сервер
	lcFile= CAST(FILETOSTR(lcPath1) as blob)

	TEXT TO lcSQL TEXTMERGE PRETEXT 15 NOSHOW

		INSERT INTO f_picture(id, dtadd, dtizm, idparent, cpath, cpic, copis) 
			VALUES (?f_picture.id, ?f_picture.dtadd, ?f_picture.dtizm,
				?f_picture.idparent, ?f_picture.cpath, ?lcPath1, ?f_picture.copis);
	ENDTEXT
		lnOk = my_SQL(lcSQL, '', .T., '')


3. Закачка на машину

    Local _CA  
    _CA=Createobject("CursorAdapter")  
    _CA.Alias="D_zagot"  
    _CA.DataSourceType="ODBC"  
    _CA.Datasource=gnHandle  
    _CA.SelectCmd="SELECT id, dtadd, dtizm, idparent, cpath, cpic, copis FROM fond_picture WHERE id = '11'"  
    _CA.CursorSchema="id C(30), dtadd T, dtizm T, idparent C(30), cpath C(254), cpic W, copis C(50)"  
    _CA.MapBinary=.T.  
    _CA.SendUpdates=.F.  
    _CA.UseCursorSchema=.T.  
    IF _CA.CursorFill(.T.,.F.)  
		lnOk = STRTOFILE(d_zagot.cPic, "d:\pic.jpg")
	ENDIF 


Всем спасибо - вопрос решен
grufos
Дата: 18.03.2015 10:04:46
alextashk,

а откуда такой параметр С7 ?
по документации у нас всего
https://odbc.postgresql.org/howto-accessvba.html
'   PG_ODBC_PARAMETER           ACCESS_PARAMETER
'   *********************************************
'   READONLY                    A0
'   PROTOCOL                    A1
'   FAKEOIDINDEX                A2  'A2 must be 0 unless A3=1
'   SHOWOIDCOLUMN               A3
'   ROWVERSIONING               A4
'   SHOWSYSTEMTABLES            A5
'   CONNSETTINGS                A6
'   FETCH                       A7
'   SOCKET                      A8
'   UNKNOWNSIZES                A9  ' range [0-2]
'   MAXVARCHARSIZE              B0
'   MAXLONGVARCHARSIZE          B1
'   DEBUG                       B2
'   COMMLOG                     B3
'   OPTIMIZER                   B4  ' note that 1 = _cancel_ generic optimizer...
'   KSQO                        B5
'   USEDECLAREFETCH             B6
'   TEXTASLONGVARCHAR           B7
'   UNKNOWNSASLONGVARCHAR       B8
'   BOOLSASCHAR                 B9
'   PARSE                       C0
'   CANCELASFREESTMT            C1
'   EXTRASYSTABLEPREFIXES       C2