PB à toute heure et à tout moment. (à parcourir avec modération)

Le forum (ô combien francophone) des utilisateurs de Powerbuilder.

Recherche rapide

Annonce

Certaines rubriques, dont des cours, sont uniquement visibles par les membres du forum ^^.
Dans la rubrique Liens & Références, vous avez accès à un sommaire de téléchargement, profitez-en !
Il existe maintenant un nouveau TOPIC "Votre CV en Ligne" accessible uniquement par demande.
  • Index
  •  » Powerscripts
  •  » Sauver un pdf depuis un disque vers une DB en passant par une DW

#1 24-10-2013 13:52:22

Shed  
Membre Geek
Date d'inscription: 06-01-2011
Messages: 62
Pépites: 260
Banque: 0

Sauver un pdf depuis un disque vers une DB en passant par une DW

Rebonjour à tous!

Voilà un petit problème qui ne trouve malheureusement pas de solution pour l'instant:
- J'ai un fichier pdf sur mon disque dur
- Je dois le charger dans une datawindow, par exemple via un ole object.
- Je dois récupérer le blob qui se trouve dans l'ole object pour mettre le pdf en DB via un update blob.

Comment vous faites ça vous? Parce que moi... je nage... Je ne peux évidemment pas me dispenser de transiter par la DW, sinon j'aurais fait autrement... Et je me fiche de l'affichage (pour l'instant en tout cas) du pdf.

Toute idée ou piste est la bienvenue!

Merci!

Hors ligne

 

#2 24-10-2013 13:57:09

buck  
Modérateur
Lieu: Dijon
Date d'inscription: 31-07-2008
Messages: 746
Pépites: 1,028,840
Banque: 171,170,849,654

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

Bonjour,

Tu me parais avoir une approche extrêmement compliqué. Il suffit de lire le fichier PDF avec les fonctions de lecture classique de fichier pour le récupérer dans un blob : FileOpen, FileReadEx, FileClose.

Puis, tu sauvegardes le blob dans la base de données avec une requête embedded SQL.

Hors ligne

 

#3 24-10-2013 13:58:43

rincevent  
Modérateur
Award: bf
Lieu: Belgique
Date d'inscription: 06-02-2007
Messages: 722
Pépites: 100,002,023
Banque: 0

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

Salut,

je vais faire mon contrariant mais... pourquoi dois-tu absolument passer par une DW ?


http://img114.imageshack.us/img114/8519/userbar175801nb.gif
Pourquoi ne puis-je vivre comme n'importe quel être humain ? Pourquoi mon destin est-il de ne pouvoir cesser de me battre ?

Hors ligne

 

#4 24-10-2013 14:23:11

Geo  
Membre completement Geek
Lieu: Binche
Date d'inscription: 15-12-2008
Messages: 119
Pépites: 378
Banque: 0

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

Salut,

on a fait ça sans OLE et sans DW, simplement en embeded SQL dans PB.
Il faut passer ton document PDF dans un BLOB (utilisation de fileopen(as_pathPDF,streammode!,Read!,LockRead!), FileReadEx(...) en boucle et FileClose(...)) puis faire un INSERT DB (sans le champs BLOB) et seulement après un UPDATEBLOB avec ton BLOB. L'insert DB se fait en 2 coups, impossible d'insérer un BLOB directement en DB.

Bons tests


Rien ne sert de courir, il faut partir à point .

Hors ligne

 

#5 24-10-2013 14:23:46

xlat  
0xc0000005
Award: bf
Lieu: Tanger (طنج)
Date d'inscription: 04-12-2010
Messages: 712
Pépites: 11,315
Banque: 100,221,387,868,884,300
Site web

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

Shed a écrit:

Je ne peux évidemment pas me dispenser de transiter par la DW, sinon j'aurais fait autrement...

Et pour quelle raison, l'utilisation de UPDATEBLOB n'est pas possible en Embedded SQL dans ton cas ?


https://lut.im/eJINqa9o/vAtyxD0h "Don't believe everything you read on the Internet"
    -- Abraham Lincoln

www.ngs.ma

Hors ligne

 

#6 24-10-2013 14:47:16

_francois_  
Bienfaiteur du site
Lieu: TOULOUSE
Date d'inscription: 25-03-2010
Messages: 151
Pépites: 178,983,268,111
Banque: 9,223,372,036,854,776,000

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

Chez nous aussi on fait l'insert en deux fois, un INSERT pour un UPDATEBLOB

Je me souviens avoir essayé de jouer un peu avec les OLE dans les DW à l'époque et je n'avais pas trouvé ça très terrible.
Par exemple ouvrir le fichier depuis la DW avec une application et le modifier pour les renvoyer après dans la DB ne marche pas avec toutes les applications.
Si mes souvenirs sont bons j'avais essayé de charger le blob dans la datawindow sans succès.

Pour l'affichage l'ActiveX Adobe ne convenant pas à nos besoin j'en ai programmé un moi même en VB.net (à l'aide de librairies tierces)

Mais il serait intéressant de connaitre la raison profonde pour laquelle tu dois absolument passer par une DW

Hors ligne

 

#7 25-10-2013 07:46:04

Shed  
Membre Geek
Date d'inscription: 06-01-2011
Messages: 62
Pépites: 260
Banque: 0

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

Chers tous,

Je suis bien d'accord avec vous sur la façon idéale et même "normale" de procéder pour aller taper un blob en db. Mais comme je vous l'ai dit dans mon post initial, je dois passer par une dw. Si vous tenez tant à savoir pourquoi, je vais essayer de vous expliquer ça assez succinctement: Nous sommes dans une application client-serveur(eas)-db. Le client est en PB et n'a évidemment pas accès à la DB, et les composants serveur sont PB aussi. Le client est codé de façon ultra générique et la seule possibilité que nous avons à l'heure actuelle pour faire transiter des données du client vers la DB est d'utiliser la datawindow. Nous nous sommes contenté de cette seule possibilité pendant des années mais nous devons aujourd'hui faire un peu évoluer les choses et permettre l'upload de fichiers (ici on commence par le pdf). On pourrait aller recoder les strates abstraites du client, mais autant dire que cela risque de nous prendre énormément de temps d'implémenter un mécanisme complémentaire (sans risquer des dommages collatéraux aux fonctionnalités qui existe déjà). C'est donc pour cela qu'on se dirige plutôt vers l'amélioration de l'existant.

Actuellement, nous avons trouvé la solution suivante (attention, code à l'arrache):

Code: pb

integer bmpno, icount, li_FileNum
string filepath, filename
blob blb_tmp, blb_tmp2, blb_tmp3
long li_fileid

// Coté client:
GetFileOpenName ( "Please select file", filepath, filename, "PDF", "PDF files (*.PDF), *.*")
dw1.object.ole_1.InsertFile (filepath)

li_fileid = FileOpen (filepath, StreamMode!)
FileReadex (li_fileid, blb_tmp)
FileClose (li_fileid)    
dw1.object.filesize[1] = len(blb_tmp)

// Coté serveur:
blb_tmp2 = dw1.object.ole_1.objectdata
blb_tmp3 = blobmid (blb_tmp2, 2544, dw1.object.filesize[1])

Notes:
- Les 2544 octets correspondent au header du wrapper ole pour un fichier pdf. Il va juste falloir trouver quelque chose de plus robuste pour déterminer la taille du header (mais ça fonctionne déjà bien ainsi)
- Le FileReadex n'est utilisé que pour obtenir la taille du fichier en octets. Je pense qu'il doit y avoir mieux comme méthode pour obtenir la taille sans passer par une variable ou on stocke le fichier.
- Je ne l'ai pas mis dans l'exemple, mais on fait évidemment un updtadeblob juste après.

Dernière modification par Shed (25-10-2013 09:23:17)

Hors ligne

 

#8 25-10-2013 08:56:16

_francois_  
Bienfaiteur du site
Lieu: TOULOUSE
Date d'inscription: 25-03-2010
Messages: 151
Pépites: 178,983,268,111
Banque: 9,223,372,036,854,776,000

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

Ce que tu pourrais faire:

Côté client tu encodes ton blob en base 64 comme ça tu peux le mettre dans ta DW dans un string et non plus un OLE.
Côté serveur tu décodés ta string base 64 et le tour est joué.

Tu as divers exemple de conversion blob / base 64 sur ce forum (surtout ne pas le faire en PB, utilise une dll C ou l'OLE MSXML sinon tu vas avoir de très mauvaises performances).
Ce n'est sûrement pas la solution idéale mais elle a le mérite d'être simple à mettre en oeuvre.

Hors ligne

 

#9 25-10-2013 09:26:11

Shed  
Membre Geek
Date d'inscription: 06-01-2011
Messages: 62
Pépites: 260
Banque: 0

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

Hummm... c'est pas con tiens... Par contre la taille du string sur une dw n'est pas limitée? Parce qu'un pdf de 10Mo, ça va faire une chiée de caractères ^^ :-D

Hors ligne

 

#10 25-10-2013 10:04:26

_francois_  
Bienfaiteur du site
Lieu: TOULOUSE
Date d'inscription: 25-03-2010
Messages: 151
Pépites: 178,983,268,111
Banque: 9,223,372,036,854,776,000

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

arf... si à 63999 caractères il me semble... je n'avais pas pensé à ça.

avec ton architecture (je n'ai jamais travaillé comme ça donc je n'en ai aucune idée) il est possible de faire des DW dynamiques ?
tu splittes ta chaine base 64 en tronçons de 63999 caractères et tu crées dynamiquement les columns dans ta DW et les lis dynamiquement sur le serveur.

Sinon il n'y a pas moyen de faire passer le fichier autrement sans tout bouleverser ? genre un petit webservice ? le faire passer avec un post HTTP ou le déposer sur un FTP ?

Hors ligne

 

#11 25-10-2013 10:10:43

xlat  
0xc0000005
Award: bf
Lieu: Tanger (طنج)
Date d'inscription: 04-12-2010
Messages: 712
Pépites: 11,315
Banque: 100,221,387,868,884,300
Site web

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

Shed a écrit:

- Le FileReadex n'est utilisé que pour obtenir la taille du fichier en octets. Je pense qu'il doit y avoir mieux comme méthode pour obtenir la taille sans passer par une variable ou on stocke le fichier.

FileLength/FileLength64(filename) ?


https://lut.im/eJINqa9o/vAtyxD0h "Don't believe everything you read on the Internet"
    -- Abraham Lincoln

www.ngs.ma

Hors ligne

 

#12 25-10-2013 11:26:30

Shed  
Membre Geek
Date d'inscription: 06-01-2011
Messages: 62
Pépites: 260
Banque: 0

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

_francois_ a écrit:

arf... si à 63999 caractères il me semble... je n'avais pas pensé à ça.

avec ton architecture (je n'ai jamais travaillé comme ça donc je n'en ai aucune idée) il est possible de faire des DW dynamiques ?
tu splittes ta chaine base 64 en tronçons de 63999 caractères et tu crées dynamiquement les columns dans ta DW et les lis dynamiquement sur le serveur.

Ce qui voudrait dire que pour un fichier de 20Mo, je vais aller créer une centaine de colonnes dynamiquement... Ca tient la route ça? Et niveau perf? Puis y'a peut-être aussi une limitation sur le nombre de colonnes...

_francois_ a écrit:

Sinon il n'y a pas moyen de faire passer le fichier autrement sans tout bouleverser ? genre un petit webservice ? le faire passer avec un post HTTP ou le déposer sur un FTP ?

Si, j'ai pensé à l'envoyer par ftp... Mais ça me fait deux protocoles de communications, des ports à ouvrir, un serveur ftp à configurer... Bref, de la gestion système supplémentaire, sans que ça reste très propre en plus.

xlat a écrit:

FileLength/FileLength64(filename) ?

En effet :-)

Hors ligne

 

#13 25-10-2013 12:13:12

_francois_  
Bienfaiteur du site
Lieu: TOULOUSE
Date d'inscription: 25-03-2010
Messages: 151
Pépites: 178,983,268,111
Banque: 9,223,372,036,854,776,000

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

bon j'ai trouvé un truc

dans ta datawindow "normale" tu insères un objet OLE de type Acrobat Reader

puis dans le code coté client tu peux charger le PDF dans l'OLE
dw_2.object.ole_1.object.loadFile("f:\xxx.pdf")

Je ne garantie pas que tu le retrouveras de l'autre coté
Mais si on le retrouve bien sur le serveur soit tu arrives à récupérer le binaire directement
Soit il faudra faite un savefile (voir le vrai de la fonction) sur le même principe que le loadFile

en tout cas ça m’intéresse de voir si ça marche, ça pourra me donner des idées pour le futur

Hors ligne

 

#14 25-10-2013 13:03:29

buck  
Modérateur
Lieu: Dijon
Date d'inscription: 31-07-2008
Messages: 746
Pépites: 1,028,840
Banque: 171,170,849,654

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

Bonjour,

C'est bien compliqué tout ça. Il te suffit d'écrire un nouveau composant sur ton serveur EAS avec une méthode prenant un blob en argument et réalisant la sauvegarde dans la base de données.

Et de coder côté client  :

Code: pb

Integer   li_fileid
Long     ll_rc
String   ls_filepath, ls_filename, ls_properties[ ]
blob     lblb_blob

connection conn
n_blob  ln_blob

conn           = create connection
conn.driver       = "jaguar"
conn.location     = "jaguar:9000"
conn.application   = "BLOB"
conn.userID     = "jagadmin"
conn.password   =   "****"

IF GetFileOpenName ( "Please select file", ls_filepath, ls_filename, "PDF", "PDF files (*.PDF), *.*") = 1 THEN
  
  li_fileid = FileOpen (ls_filepath, StreamMode!)
  FileReadex (li_fileid, lblb_blob)
  FileClose (li_fileid)    
  
  ll_rc = conn.ConnectToServer()

  IF ll_rc <> 0 THEN
       MessageBox("Connexion échoué", ll_rc)
    RETURN
  END IF
  
  ll_rc = conn.CreateInstance( ln_blob  , "BLOB/n_blob")
  IF ll_rc  = 0 THEN
    ln_blob.uf_save(ls_filepath, lblb_blob)
  ELSE
    MessageBox("Création échoué", ll_rc)
  END IF  
  
END IF

conn.DisconnectServer()

Hors ligne

 

#15 25-10-2013 13:19:50

Shed  
Membre Geek
Date d'inscription: 06-01-2011
Messages: 62
Pépites: 260
Banque: 0

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

buck, je sais comment effectuer une connexion au serveur et lui filer un blob. Mais comme je l'ai dit, je dois faire ça dans une application client lourde et abstraite qui possède un framework super restrictif. Je ne peux pas coder ce genre de chose, le framework de l'appli impose de passer par une DW pour passer des données au serveur. Et comme je l'ai déjà dit, je ne toucherai pas à ce framework.

Dernière modification par Shed (25-10-2013 13:22:24)

Hors ligne

 

#16 25-10-2013 13:22:02

Shed  
Membre Geek
Date d'inscription: 06-01-2011
Messages: 62
Pépites: 260
Banque: 0

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

_francois_ a écrit:

bon j'ai trouvé un truc

dans ta datawindow "normale" tu insères un objet OLE de type Acrobat Reader

puis dans le code coté client tu peux charger le PDF dans l'OLE
dw_2.object.ole_1.object.loadFile("f:\xxx.pdf")

Je ne garantie pas que tu le retrouveras de l'autre coté
Mais si on le retrouve bien sur le serveur soit tu arrives à récupérer le binaire directement
Soit il faudra faite un savefile (voir le vrai de la fonction) sur le même principe que le loadFile

en tout cas ça m’intéresse de voir si ça marche, ça pourra me donner des idées pour le futur

Charger le fichier, ça marche nickel. Le récupérer depuis l'OLE sur le serveur, c'est une autre paire de manche:
.objectdata = --> Ca marche pas
.savefile ---> Ca marche pas

La liste des functions de l'objet ne présente pas de sauvegarde possible (trouvée sur le net) et je n'ai pas accès aux propriétés de l'objet pour en extirper le blob.

... L'objet est bien dans l'OLE, mais je trouve pas comment le récupérer dans mon blob...

Dernière modification par Shed (25-10-2013 14:11:08)

Hors ligne

 

#17 25-10-2013 13:38:03

Geo  
Membre completement Geek
Lieu: Binche
Date d'inscription: 15-12-2008
Messages: 119
Pépites: 378
Banque: 0

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

Côté serveur, peux-tu avoir accès à un répertoire (accessible aussi par les clients) ?
Si oui, tu pourrais :
- côté client : sélectionner le PDF local, faire une copie dans le répertoire accessible par le serveur, passer le chemin d'accès au PDF copié via ta DW
- côté serveur : récupérer le path dans la DW et procéder à la sauvegarde "normale"

C'est envisageable ça ?


Rien ne sert de courir, il faut partir à point .

Hors ligne

 

#18 25-10-2013 13:51:59

Shed  
Membre Geek
Date d'inscription: 06-01-2011
Messages: 62
Pépites: 260
Banque: 0

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

Oui ça marcherait mais non. Partager un dossier entre mes clients et mon serveur, c'est la porte ouverte des enfers
Au mieux, comme je l'ai déjà dit, j'ai pensé à l'envoi ftp. Mais c'est pas propre d'avoir deux protocoles de communication.

Hors ligne

 

#19 28-10-2013 12:36:38

_francois_  
Bienfaiteur du site
Lieu: TOULOUSE
Date d'inscription: 25-03-2010
Messages: 151
Pépites: 178,983,268,111
Banque: 9,223,372,036,854,776,000

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

Et programmer ton propre Ole Object / utiliser autre chose que Acrobat Reader pour avoir un save côté serveur ?
Est-ce que tu sais déterminer si le binaire arrive bien côté serveur ou non ?

Hors ligne

 

#20 28-10-2013 13:52:25

Shed  
Membre Geek
Date d'inscription: 06-01-2011
Messages: 62
Pépites: 260
Banque: 0

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

_francois_ a écrit:

Et programmer ton propre Ole Object / utiliser autre chose que Acrobat Reader pour avoir un save côté serveur ?



Sinon, sans rire, trouver des objets qui font des save, doit y en avoir, mais faut encore pouvoir charger un fichier pdf dedans...

_francois_ a écrit:

Est-ce que tu sais déterminer si le binaire arrive bien côté serveur ou non ?

A priori oui, ça passe juste par un getfullstate/setfullstate qui ne fait juste qu'envelopper la dw.

On a testé la méthode en passant par un string, c'est vraiment dommage d'être limité à 32ko par string car c'est ultrarapide.

Hors ligne

 

#21 29-10-2013 14:01:46

_francois_  
Bienfaiteur du site
Lieu: TOULOUSE
Date d'inscription: 25-03-2010
Messages: 151
Pépites: 178,983,268,111
Banque: 9,223,372,036,854,776,000

Re: Sauver un pdf depuis un disque vers une DB en passant par une DW

Shed a écrit:

_francois_ a écrit:

Et programmer ton propre Ole Object / utiliser autre chose que Acrobat Reader pour avoir un save côté serveur ?



Sinon, sans rire, trouver des objets qui font des save, doit y en avoir, mais faut encore pouvoir charger un fichier pdf dedans...

Mais non c'est super facile (la preuve j'en ai fait un en début d'année sans expérience dans le domaine ou en .net)
Il suffit d'avoir un VB.net (Express suffit)
Installer le Microsoft Interop Forms Toolkit
Et faire un nouveau projet "VB6 Interop UserControl"
Une fonction qui sauvegarde ton blob dans un byte() (pas besoin de conversion)
une fonction qui return le byte()

Bon après il faut déployer l'ActiveX chez le(s) client(s)

Sinon si tu trouves comment mettre un OLE non visual dans une datawindow il faut mettre une classe Msxml2.DOMDocument.6.0

Si jamais tu veux tenter le coup je veux bien essayer de te filer un coup de mail

Hors ligne

 
  • Index
  •  » Powerscripts
  •  » Sauver un pdf depuis un disque vers une DB en passant par une DW

Pied de page des forums

Propulsé par FluxBB 1.2.22