Base Sqlite et Utilisation de PostGreSQL

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
omega
Messages : 617
Inscription : sam. 26/nov./2011 13:04
Localisation : Alger

Base Sqlite et Utilisation de PostGreSQL

Message par omega »

Bonjour à tous
J'ai développé une application pharmaceutique (utilisant une base sqlite) pour un client qui l'utilise (en monoposte) depuis plusieurs années et ça marche bien, sans aucun problème. Aujourd'hui, mon client souhaite exploiter ce logiciel sur 2 postes distincts séparés sur une petite distance de 3 mètres seulement, donc sous réseau local simple. Comme sqlite ne gère pas les réseaux, j'ai pensé utiliser PostGreSQL. Maintenant, je ne sais plus quoi faire ni par quoi commencer.
1. Je suppose que je dois installer PostgreSQL sur les 2 postes ?
2. Dois-je utiliser ma base sqlite existante ou faut il recréer la base avec postgreslq? (à ce moment là les données seront perdues?)
3. Au niveau du code, quels sont les changements à porter (à part use PostgreSQL Database + la connexion à la base)?
4. Y a t il une possibilité de ne pas perdre mes données sur la base existante (sqlite)?
Falsam m'a déjà expliqué un jour comment utiliser PostGreSQL malheureusement, j'ai noté uniquement la syntaxe de la connexion à la base PostGreSQL + Use PostgreSQL) le reste me paraissait identique à sqlite (en terme de syntaxe). Mais là, il s'agit d'une application opérationnelle dont la base contient des données. Mon plus grand souci c'est de ne pas perdre les données existante sur ma base sqlite( si c possible bien entendu).

Merci de votre aide
Win7 (x64) 64 bits Pb 5.72
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Re: Base Sqlite et Utilisation de PostGreSQL

Message par boby »

Tu peux le faire en SQLite.
il te faut 2 logiciel : client et un serveur
SEUL le serveur sera connecté à la base SQL, les client envoie les requetes au serveur, le srv leur renvoi le résulta.

Une base de donnée ne doit être accécible uniquement en localhost pour des raisons de sécurité primaire.
Avatar de l’utilisateur
omega
Messages : 617
Inscription : sam. 26/nov./2011 13:04
Localisation : Alger

Re: Base Sqlite et Utilisation de PostGreSQL

Message par omega »

Bonjour Boby
Tu peux le faire en SQLite.
il te faut 2 logiciel : client et un serveur
SEUL le serveur sera connecté à la base SQL, les client envoie les requetes au serveur, le srv leur renvoi le résulta.
Tu veux dire que je n'ai pas besoin de PostGreSQL? Les 2 logiciels seront ils identiques ou différents?
J'avoue que je n'ai pas très bien saisi Boby ! Puis-je avoir un petit exemple si cela ne te dérange pas?

Merci
Win7 (x64) 64 bits Pb 5.72
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Re: Base Sqlite et Utilisation de PostGreSQL

Message par boby »

Tu veux dire que je n'ai pas besoin de PostGreSQL?
Tu peux le faire via postfre ou sqlite c'est toi qui décide.
Dans les deux cas tu auras besoin d'un logiciel serveur et d'un logiciel client
Les 2 logiciels seront ils identiques ou différents?
Rien à voir, le serveur sera la parti qui à accès à la base SQL, le client sera ton logiciel actuel, sauf qu'au lieu d'accéder directement à la base SQL, il devra passer par le serveur pour ses requetes
Ca évite d'avoir 2 PC qui font une requête en même temps, ce qui aurais pour effet de faire "kaboom" ta base SQL et d'être sécurisé.

Je t'ai fait un petit exemple, à savoir que dans ton cas, 2 client c'est pas beaucoup donc un serveur monothread fera le boulot et sera plus simple à coder, mais si tu souhaite faire le même genre
de code client/serveur, avec plusieurs connections en même temps, il faudra multithread ton serveur.

Serveur :

Code : Tout sélectionner

EnableExplicit
InitNetwork()
;UseSQLiteDatabase()
Structure client
  ID.I
  *Data
  DataReceive.i
  DataSize.i
EndStructure
Enumeration
  #PRT_bla
  #PRT_blabla
EndEnumeration
Global NewList client.client(), *networkbuffer = AllocateMemory(65536)
Declare RequestEvent(*ClientData)
If CreateNetworkServer(0,5555)
  ;Ouvre ta base SQL ici
  Repeat
    Select NetworkServerEvent(0)
      Case #PB_NetworkEvent_None
        Delay(10)
      Case #PB_NetworkEvent_Data
        ForEach client()
          If client()\ID = EventClient()
            If client()\DataSize
              client()\DataReceive + ReceiveNetworkData(client()\ID,client()\Data,client()\DataSize-client()\DataReceive)
            Else
              ReceiveNetworkData(client()\ID,*networkbuffer,SizeOf(long))
              client()\Data = AllocateMemory(PeekL(*networkbuffer))
              client()\DataSize = PeekL(*networkbuffer)
              client()\DataReceive = ReceiveNetworkData(client()\ID,client()\Data,client()\DataSize)
            EndIf
            Break
          EndIf
        Next
        If client()\DataReceive = client()\DataSize
          client()\DataReceive = 0
          client()\DataSize = 0
          RequestEvent(@client())
        EndIf
      Case #PB_NetworkEvent_Connect
        AddElement(client())
        client()\ID = EventClient()
      Case #PB_NetworkEvent_Disconnect
        ForEach client()
          If client()\ID = EventClient()
            If client()\DataSize
              FreeMemory(client()\Data)
            EndIf
            DeleteElement(client())
            Break
          EndIf
        Next
    EndSelect
    
  ForEver
  

EndIf
Procedure RequestEvent(*ClientData.client)
  Protected size
  Select PeekA(*ClientData\Data)
    Case #PRT_bla
      ;En vrais ça devrais correspontre à tes requetes
      Debug "j'ai recu un bla"
    Case #PRT_blabla
      size = SizeOf(ascii)+Len("bla bla blaaaaa")*2+2
      Debug "j'ai recu "+PeekS(*ClientData\Data+SizeOf(ascii))
      PokeL(*networkbuffer,size)
      PokeA(*networkbuffer+SizeOf(long),#PRT_blabla)
      PokeS(*networkbuffer+SizeOf(long)+SizeOf(ascii),"bla bla blaaaaa")
      SendNetworkData(*ClientData\ID,*networkbuffer,size+SizeOf(long))
      Delay(10)
  EndSelect
  FreeMemory(*ClientData\Data)
EndProcedure
Client :

Code : Tout sélectionner

EnableExplicit
InitNetwork()
Enumeration
  #PRT_bla
  #PRT_blabla
EndEnumeration
Global *networkbuffer = AllocateMemory(65536), connection
connection = OpenNetworkConnection("127.0.0.1",5555)
If Not connection
  MessageRequester("connection","impossible de se connecter")
  End
EndIf
Declare SendStr()
Declare SendBla()
Declare Close()
Declare Network()
If OpenWindow(0,0,0,200,300,"bla",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  StringGadget(0,10,10,100,20,"")
  ButtonGadget(1,10,40,80,20,"envoyer la str")
  ButtonGadget(2,110,40,80,20,"envoyer un bla")
  BindEvent(#PB_Event_CloseWindow,@Close())
  BindGadgetEvent(1,@SendStr())
  BindGadgetEvent(2,@SendBla())
EndIf

Repeat : WaitWindowEvent(10) : Network() : ForEver

Procedure Close()
  End
EndProcedure

Procedure SendBla()
  PokeL(*networkbuffer,SizeOf(ascii))
  PokeA(*networkbuffer+SizeOf(long),#PRT_bla)
  SendNetworkData(connection,*networkbuffer,SizeOf(long)+SizeOf(ascii))
EndProcedure

Procedure SendStr()
  Protected size
  size = SizeOf(ascii)+Len(GetGadgetText(0))*2+2
  PokeL(*networkbuffer,size)
  PokeA(*networkbuffer+SizeOf(long),SizeOf(ascii))
  PokeS(*networkbuffer+SizeOf(long)+SizeOf(ascii),GetGadgetText(0))
  SendNetworkData(connection,*networkbuffer,size+SizeOf(long))
  Delay(10)
EndProcedure

Procedure Network()
  Protected size, receivedsize
  If NetworkClientEvent(connection) = #PB_NetworkEvent_Data
    ReceiveNetworkData(connection,*networkbuffer,SizeOf(long))
    size = PeekL(*networkbuffer)
    Repeat
      receivedsize + ReceiveNetworkData(connection,*networkbuffer+receivedsize,size-receivedsize)
      ;!!!!!!!!!!!!!!!!!!! C'est un exemple donc je suis un flémard, mais la feinte c'est qu'ici receivenetworkdata peut renvoyer -1 si le réseau est occupé !!!
      ;Il faut gérer cet cas pour ne pas rentrer dans une boucle infinit !!!!!!!
    Until size = receivedsize
    Select PeekA(*networkbuffer)
      Case #PRT_blabla
        Debug PeekS(*networkbuffer+SizeOf(ascii))
        
    EndSelect
  EndIf
EndProcedure
  
Marc56
Messages : 2146
Inscription : sam. 08/févr./2014 15:19

Re: Base Sqlite et Utilisation de PostGreSQL

Message par Marc56 »

Si tu n'as que 2 utilisateurs
Qu'il y a majoritairement des lectures
Que les écritures peuvent êtres faites rapidement
Qu'il n'y a pas besoin de verrouiller un enregistrement le temps d'éditer
Alors tu peux rester en SQLite
Référence: https://sqlite.org/faq.html#q5
SQLite ne gère pas les réseaux, mais tu peux mettre le fichier de la base sur un dossier partagé.

Dans le cas contraire, PostgreSQL est idéal
- Tu ne l'installe que sur un poste (idéalement sur un serveur enfermé dans une autre pièce. Ton serveur peut être une machine Linux, même une carte Raspberry)
- Tu construis ensuite tes applications clientes uniquement en PB. Il n'y a même pas besoin d'installer un pilote ODBC puisque PB gère nativement PostgreSQL
- Tu peux bien sur importer tes données et structures dans PostgreSQL
Mais
- Il va faloir apprendre quelques notions supplémentaires (gestion des utilisateurs et des connexions réseau à la base de donnée)
https://docs.postgresql.fr/10/client-au ... ation.html
- Tu es dans le cas d'un réseau local, avec plusieurs clients la base de données doit donc être accessible directement et non pas en localhost, auquel cas, seul le client installé sur le serveur peut accéder aux données. (Ne pas confondre avec les architectures 3 tiers utilisées souvent sur Internet, où effectivement on préfère faire tourner le serveur sur la machine qui héberge aussi le générateur de pages (ex: PHP) et le serveur web (ex: Apache), donc pour limiter le risque on se limite à localhost (127.0.0.1). Bien sur qu'on peut utiliser des bases de données sur des serveurs différents, sinon, on serait mal pour la réplication.
- Les données PostgreSQL ne sont pas contenues dans un seul fichier comme SQLite, donc tu dois penser à faire des sauvegardes soit en binaires (nécessite d'arrêter la base) soit en texte (DUMP) qui ne nécessite pas d'arrêter la base.
- PostgreSQL verrouille au niveau enregistrement et non pas au niveau table, ce qui permet à plusieurs personnes d'écrire en même temps (deux enrgistrements différents) ce que ne fait pas SQLite
- À part la chaine de connexion et la syntaxe de SetDatabaseString etc qui sont différentes, le reste est identique.
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Base Sqlite et Utilisation de PostGreSQL

Message par falsam »

Omega a écrit :Falsam m'a déjà expliqué un jour comment utiliser PostGreSQL malheureusement, j'ai noté uniquement la syntaxe de la connexion à la base PostGreSQL + Use PostgreSQL) le reste me paraissait identique à sqlite (en terme de syntaxe)
Oui on en a déja parlé en 2014 et 2017 :mrgreen:

Que ce soit PostGreSQL ou SQLite la syntaxe de manipulation de la base de données est la même car tu utilises SQL.

Exemple de création d'une table

Code : Tout sélectionner

CREATE TABLE jeux (
  idauto integer Not NULL,
  titre text,
  editeur text,
  annee integer
);
J'ai inséré 5 titres de jeux.

Identifiant de connexion
-Host (C'est le serveur) postgresql-falsam.alwaysdata.net
-Port 5432
-Base de données falsam_01
-Utilisateur falsamdemo
-Password purebasicdemo

Le code de connexion à la base de données

Code : Tout sélectionner

OpenDatabase(#Database, "host=postgresql-falsam.alwaysdata.net port=5432 dbname=falsam_01", "falsamdemo", "purebasicdemo", #PB_Database_PostgreSQL)
■ Code de sélection de l'ensemble des titres.

Code : Tout sélectionner

UsePostgreSQLDatabase()

Enumeration
  #Database
EndEnumeration

Global ReqSql.s, Buffer.s

;Connection à la base de données PostgreSQL
If OpenDatabase(#Database, "host=postgresql-falsam.alwaysdata.net port=5432 dbname=falsam_01", "falsamdemo", "purebasicdemo", #PB_Database_PostgreSQL)
  Debug "Connected to PostgreSQL"
  
  ;Execution d'une requête de sélection
  ReqSql="select * from jeux order by annee asc"
  DatabaseQuery(#Database, ReqSql)
  
  ;Affichage du résultat
  If DatabaseQuery(#Database, ReqSql)
    While NextDatabaseRow(#Database)
      Buffer = GetDatabaseString(#Database, 1)              ; Titre du jeu
      Buffer + " (" + GetDatabaseString(#Database, 2)       ; Editeur
      Buffer + " - " + GetDatabaseLong(#Database, 3) + ")"  ;Année 
      
      Debug Buffer
    Wend
  EndIf  
  
  ;Fermeture de la base de données 
  CloseDatabase(#Database)
  
Else
  Debug "Connection failed: "+DatabaseError()
EndIf
je te laisse le soin d’exécuter ce code :wink:
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Marc56
Messages : 2146
Inscription : sam. 08/févr./2014 15:19

Re: Base Sqlite et Utilisation de PostGreSQL

Message par Marc56 »

Ne pas oublier la différence entre SQLite et PostgreSQL quant à l'utilisation du très utile "SetDatabaseString", commande qui permet manipuler des chaines de caractères comportant par exemple des guillemets sans avoir à "échapper" les caractères.
SQLite et ODBC utilisent '?' et PostgreSQL '$1'
Je ne sais pas pourquoi il y a deux syntaxes ? La deuxième est plus logique. Mais il y a peut-être une raison historique.

cf: https://www.purebasic.com/french/docume ... query.html

Code : Tout sélectionner

Exemple: Variables liées avec SQLite et ODBC

      ; SQLite et ODBC partagent la même syntaxe pour les variables de liaison, indiquées par le caractère "?" 
      ;
      SetDatabaseString(#Database, 0, "test")  
      If DatabaseQuery(#Database, "SELECT * FROM employee WHERE id=?")    
        ; ...
      EndIf

Exemple: PostgreSQL

      ; PostgreSQL utilise une autre syntaxe dans la déclaration: 1 $, 2 $ ..  pour indiquer le paramètre indéfini
      ;
      SetDatabaseString(#Database, 0, "test")  
      If DatabaseQuery(#Database, "SELECT * FROM employee WHERE id=$1")    
        ; ...
      EndIf
Répondre