Jak zakodować prosty system wersjonowania?

Chcę zrobić prosty system wersjonowania, ale nie mam pomysłów, jak uporządkować moje dane i mój kod.

Oto krótki przykład:

  1. użytkownik loguje się
  2. Użytkownik ma dwie opcje podczas przesyłania pliku:
    • Prześlij nowy plik
    • Prześlij nową wersję pliku

Użytkownicy powinni być w stanie zobaczyć drzewo. (inna wersja) Drzewo może mieć tylko 2 poziomy:

|
|--File_A_0
 \--File_A_1
 \--File_A_2
 \--File_A_3
 \--File_A_4

Istnieją również 2 rodzaje plików, ostateczny (która jest najnowszą zatwierdzoną wersją) I wersję roboczą (która jest najnowszym przesłanym plikiem) Plik zostanie fizycznie zapisany na serwerze. Każdy plik jest własnością użytkownika (lub więcej) i tylko jednej grupy.

Edit: grupy reprezentują grupę dokumentu, dokument może być własnością tylko jednej grupy naraz. Użytkownicy nie zależą od grup.

Początek edycji:

Oto, co zrobiłem, ale to nie jest naprawdę skuteczne !

id_article | relative_group_id | id_group | title | submited | date | abstract | reference | draft_version | count | status

id_draft | id_file | version | date

Ale to trudne do opanowania, rozszerzyć. Myślę, że to dlatego, że grupa paramater...

End edit

Więc pytania są:

  • jak schematyzować bazę danych ?
  • jakie informacje powinny być przydatne do wersji tej pracy ?
  • jaki rodzaj struktury dla foldery, pliki ?
  • jakie masz porady, wskazówki do tego rodzaju pracy ?

(aplikacja jest rozwijana w PHP i Zend Framework, bazą danych powinna być mysql lub postgresql)

Author: Boris Guéry, 2009-06-10

13 answers

Na miłość boską, nie . Naprawdę nie chcesz iść tą drogą.

Zatrzymaj się i zastanów się przez chwilę nad szerszym obrazem. Chcesz zachować wcześniejsze wersje dokumentów, co oznacza, że w pewnym momencie ktoś będzie chciał zobaczyć niektóre z tych wcześniejszych wersji, prawda? A potem zapytają, "Jaka jest różnica między wersją 3 A wersją 7"? i wtedy powiedzą, "chcę wrócić do wersji 3, ale zachowaj trochę zmiany, które umieściłem w wersji 5, hmmm, ok?"

Kontrola wersji jest nietrywialna i nie ma potrzeby odkrywania koła na nowo-istnieje wiele sprawnych systemów kontroli wersji, niektóre z nich są nawet darmowe.

Na dłuższą metę znacznie łatwiej będzie poznać API jednego z tych systemów i zakodować front-end internetowy, który oferuje użytkownikom podzbiór funkcji, których szukają (teraz.)

Nie kodowałbyś edytora tekstu dla swoich użytkowników, prawda?

 48
Author: Michael Dorfman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-15 18:53:08

Możesz czerpać inspirację z tam .


Odnośnie Twojego komentarza:

Jeśli chodzi o strukturę bazy danych, możesz spróbować tego rodzaju struktury (MySQL sql):

CREATE TABLE `Users` (
       `UserID` INT NOT NULL AUTO_INCREMENT
     , `UserName` CHAR(50) NOT NULL
     , `UserLogin` CHAR(20) NOT NULL
     , PRIMARY KEY (`UserID`)
);

CREATE TABLE `Groups` (
       `GroupID` INT NOT NULL AUTO_INCREMENT
     , `GroupName` CHAR(20) NOT NULL
     , PRIMARY KEY (`GroupID`)
);

CREATE TABLE `Documents` (
       `DocID` INT NOT NULL AUTO_INCREMENT
     , `GroupID` INT NOT NULL
     , `DocName` CHAR(50) NOT NULL
     , `DocDateCreated` DATETIME NOT NULL
     , PRIMARY KEY (`DocID`)
     , INDEX (`GroupID`)
     , CONSTRAINT `FK_Documents_1` FOREIGN KEY (`GroupID`)
                  REFERENCES `Groups` (`GroupID`)
);

CREATE TABLE `Revisions` (
       `RevID` INT NOT NULL AUTO_INCREMENT
     , `DocID` INT
     , `RevUserFileName` CHAR(30) NOT NULL
     , `RevServerFilePath` CHAR(255) NOT NULL
     , `RevDateUpload` DATETIME NOT NULL
     , `RevAccepted` BOOLEAN NOT NULL
     , PRIMARY KEY (`RevID`)
     , INDEX (`DocID`)
     , CONSTRAINT `FK_Revisions_1` FOREIGN KEY (`DocID`)
                  REFERENCES `Documents` (`DocID`)
);

CREATE TABLE `M2M_UserRev` (
       `UserID` INT NOT NULL
     , `RevID` INT NOT NULL
     , INDEX (`UserID`)
     , CONSTRAINT `FK_M2M_UserRev_1` FOREIGN KEY (`UserID`)
                  REFERENCES `Users` (`UserID`)
     , INDEX (`RevID`)
     , CONSTRAINT `FK_M2M_UserRev_2` FOREIGN KEY (`RevID`)
                  REFERENCES `Revisions` (`RevID`)
);

Documents jest kontenerem logicznym, a Revisions zawiera rzeczywiste łącza do plików. Za każdym razem, gdy dana osoba aktualizuje nowy Plik, Utwórz wpis w każdej z tych tabel, ten w wersji zawierający łącze do tego wstawionego w dokumentach.

Tabela M2M_UserRev pozwala na przy każdej wersji dokumentu można przypisać kilku użytkowników.

Gdy aktualizujesz dokument, wstawiaj tylko wersje, za pomocą linku do odpowiedniego dokumentu. Aby dowiedzieć się, do którego dokumentu należy połączyć, możesz użyć konwencji nazewnictwa lub poprosić Użytkownika o wybranie odpowiedniego dokumentu.

Dla architektury systemu plików plików, to naprawdę nie ma znaczenia. Po prostu zmieniłbym nazwy moich plików na coś unikalnego, zanim zostaną zapisane na serwerze i zachowałbym nazwę pliku użytkownika w bazie danych. Po prostu przechowuj zmienione pliki w dowolnym folderze i zachowaj ścieżkę do nich w bazie danych. W ten sposób wiesz, jak zmienić nazwę, gdy użytkownik o to poprosi. Równie dobrze możesz zachować oryginalną nazwę podaną przez użytkownika, jeśli jesteś pewien, że będzie unikalna, ale nie polegałbym na niej zbytnio. Wkrótce mogą pojawić się dwie różne wersje o tej samej nazwie, a jedna nadpisuje drugą w systemie plików.

 18
Author: subtenante,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-15 13:51:44

Schemat bazy danych


Aby zachować to wyjątkowo proste, wybrałbym następujący projekt bazy danych. Oddzielam koncepcję" file "(taką samą jak system plików) od koncepcji" document " (gerarchiczna Grupa dokumentów).

User entity:

  • userId
  • nazwa użytkownika

Grupa entity:

  • groupId
  • nazwa grupy

Plik entity:

  • fileId (Sekwencja)
  • fileName (nazwa nadana przez użytkownika do pliku)
  • filesystemFullPath
  • uploadTime
  • W tym celu należy skontaktować się z działem obsługi klienta.]}
  • ownerGroupId

Dokument entity:

  • documentId
  • parentDocumentId
  • fileId
  • versionNumber
  • creationTime
  • isApproved

Za każdym razem, gdy przesyłany jest nowy plik, tworzony jest rekord "plik", a także nowy "dokument". Jeśli plik jest przesyłany po raz pierwszy, parentDocumentId dla tego dokumentu będzie równy NULL. W przeciwnym razie nowy rekord dokumentu wskazywałby na pierwszą wersję.

Pole "isApproved" (boolean) będzie obsługiwał dokument będący projektem lub zatwierdzoną rewizją.
otrzymujesz najnowszy projekt dokumentu po prostu zamawiając malejąco według numeru wersji lub czasu przesłania.

Podpowiedzi


Z tego, jak opisujesz problem, powinieneś lepiej przeanalizować te aspekty, zanim przejdziesz do projektu schematu bazy danych:

  • jaka jest rola podmiotu "grupowego"?
  • Jak są powiązane grupy/Użytkownicy / pliki?
  • co jeśli dwóch użytkowników z różnych grup spróbuj przesłać ten sam dokument?
  • będziesz potrzebował folderów? (prawdopodobnie będziesz; moje rozwiązanie jest nadal ważne, podając Typ" folder "lub" dokument "encji" dokument")

Mam nadzieję, że to pomoże.

 13
Author: Gabriele D'Antona,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-13 11:03:16

Czy istniejące rozwiązanie kontroli wersji może działać lepiej niż własne? Subversion można zrobić większość tego, co chcesz, i to jest właśnie tutaj.

 9
Author: David Thornley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-13 15:57:15

Tworzenie bogatej struktury danych w tradycyjnej relacyjnej bazie danych, takiej jak MySQL, może być często trudne i istnieją o wiele lepsze sposoby na to. Podczas pracy ze strukturą danych opartą na ścieżkach z hierarchią lubię tworzyć system oparty na plikach płaskich, który używa formatu serializacji danych, takiego jak JSON do przechowywania informacji o konkretnym pliku, katalogu lub całym repozytorium.

W ten sposób możesz użyć dostępnych obecnie narzędzi do nawigacji i manipulowania strukturą łatwo i można czytać, edytować i zrozumieć strukturę łatwo. XML jest do tego dobry - jest nieco bardziej wyrazisty niż JSON, ale łatwy do odczytania i dobry do przesyłania wiadomości i innych systemów opartych na XML.

Szybki przykład. Jeśli mamy repozytorium, które ma katalog i trzy pliki. Patrząc na to z przodu będzie wyglądać tak:

/repo
  /folder
    code.php
  file.txt
  image.jpg

Możemy mieć folder metadanych, który zawiera nasze pliki JSON, ukryte przed systemem operacyjnym, w katalogu głównym każdego katalogu, które opisują zawartość tego katalogu. Tak działają tradycyjne systemy wersjonowania, z wyjątkiem tego, że używają niestandardowego języka zamiast JSON.

/repo
  */.folderdata*
  /code
    */.folderdata*
    code.php
  file.txt
  image.jpg

Każdy .folder folderdata może zawierać własną strukturę, której możemy użyć do prawidłowego uporządkowania danych folderu. Każdy .folder folderdata może zostać skompresowany w celu zaoszczędzenia miejsca na dysku. Jeśli spojrzymy na .Folder Folder wewnątrz katalogu / code:

*/.folderdata*
  /revisions
    code.php.r1
    code.php.r2
    code.php.r3
  folderstructure.json
  filerevisions.json

Struktura folderów określa strukturę naszego folderu, gdzie pliki i foldery są względem siebie itp. To może wyglądać mniej więcej tak:

{
  '.':        'code',
  '..':       'repo',
  'code.php': {
    'author_id': 11543,
    'author_name': 'Jamie Rumbelow',
    'file_hash': 'a26hb3vpq22'
    'access': 'public'
  }
}

Pozwala nam to kojarzyć metadane dotyczące tego pliku, sprawdzać autentyczność i integralność, przechowywać trwałe DANE, określać atrybuty plików i robić wiele więcej. Następnie możemy przechowywać informacje o konkretnych wersjach w filerevisions.plik json:

{
  'code.php': [
    1: {
      'commit': 'ah32mncnj654oidfd',
      'commit_author_id': 11543,
      'commit_author_name': 'Jamie Rumbelow',
      'commit_message': 'Made some changes to code.php',
      'additions': 2,
      'subtractions': 4
    },
    2: {
      'commit': 'ljk4klj34khn5nkk5',
      'commit_author_id': 18676,
      'commit_author_name': 'Jo Johnson',
      'commit_message': 'Fixed Jamie\'s bad code!',
      'additions': 2,
      'subtractions': 0
    },
    3: {
      'commit': '77sdnjhhh4ife943r',
      'commit_author_id': 11543,
      'commit_author_name': 'Jamie Rumbelow',
      'commit_message': 'Whoah, showstopper found and fixed',
      'additions': 8,
      'subtractions': 5
    },
  ]
}

Jest to podstawowy plan dla systemu wersjonowania plików-podoba mi się ten pomysł i jak to działa, a ja użyłem JSON w przeszłość z wielkim skutkiem z bogatymi strukturami danych, takimi jak ta. Ten rodzaj danych po prostu nie nadaje się do relacyjnej bazy danych, takiej jak MySQL - jak uzyskać więcej wersji i więcej plików baza danych będzie rosnąć większe i większe, w ten sposób można przesuwać zmiany w wielu plikach, zachować kopie zapasowe wszystkiego, upewnij się, że masz trwałe DANE w różnych interfejsach i platformach itp.

Mam nadzieję, że to dało ci trochę wglądu i mam nadzieję, że dostarczy Ci pożywienia do przemyśleń społeczność też!

 6
Author: Jamie Rumbelow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-15 15:08:02

Dla schematu bazy danych, prawdopodobnie potrzebujesz dwóch zestawów informacji, plików i wersji plików. Gdy nowy plik jest przechowywany, tworzona jest również początkowa wersja. Najnowsza zatwierdzona wersja musi być zapisana jawnie, podczas gdy najnowsza wersja może być wybrana z tabeli wersji (albo znajdując najwyższą wersję związaną z plikiem, lub najnowszą datę, jeśli przechowujesz ją podczas ich tworzenia)

files(id,name,approved_version)
file_versions(id,fileId)

Wersje plików mogą być następnie przechowywane przy użyciu ich identyfikatorów (np., '/fileId / versionId ' lub '/ fileId / versionId_fileName') na serwerze, z oryginalną nazwą przechowywaną w bazie danych.

 2
Author: gapple,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-09 23:51:24

Niedawno zbudowałem prosty system wersjonowania dla niektórych statycznych jednostek danych. Wymaganiem było posiadanie wersji "aktywnej" i wersji 0 LUB 1 "oczekujących".

W końcu mój wersjonowany byt miał następujące atrybuty istotne dla wersjonowania.

VersionNumber (int / long) ActiveVersionFlag (boolean)

Gdzie:-

  • Tylko 1 encja może być ActiveVersionFlag = ' Y '
  • tylko 1 encja może być numerem wersji > wersji 'aktywnej' (tzn. "pending" version)

Rodzaje operacji, na które pozwoliłem to

Klonowanie bieżącej wersji.

  • Fail jeśli istnieje już wersja > Numer wersji 'aktywnej' wersji
  • skopiuj wszystkie dane do nowej wersji
  • zwiększ numer wersji o jeden

Aktywuj Oczekującą Wersję

  • Fail if the specified version is not the 'Active' version + 1
  • znajdź wersję 'Active' i ustaw jej ActiveVersionFlag na "N"
  • Ustaw ActiveVersionFlag wersji ' pending 'na' Y '

Usuń Oczekującą Wersję

  • Usuń oczekujący podmiot

To było dość udane, a moi użytkownicy teraz klonują i aktywują cały czas:)

Michael

 2
Author: Michael Dausmann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-19 05:09:25

Zacznij od istniejącego systemu zarządzania treścią , wykonanego w PHP i MySQL, jeśli są to twoje wymagania, takie jak eZ Publishlub Knowledgetree. Do szybkiego testowania tych aplikacji, Bitnami zapewnia szybkie do zainstalowania " stosy " z nich również (WAMP-stosy na sterydach).

Następnie możesz dostosować te aplikacje do potrzeb organizacji i być na bieżąco ze zmianami na wcześniejszych etapach.

 1
Author: maxwellb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-17 15:54:06

Jako alternatywa dla mojego poprzedniego postu, jeśli uważasz, że struktura hierarchiczna byłaby najlepsza, możesz użyć pamięci płaskich plików i udostępnić API za pośrednictwem usługi internetowej.

Serwer będzie miał swój główny katalog danych i możesz przechowywać grupy (pliki) w folderach, z głównym wpisem metadanych w każdym folderze. (XML może?)

Następnie możesz użyć istniejącego narzędzia kontroli wersji zawiniętego w API lub zwijać własne, zachowując wersje plików w folderze Wersje pod elementem w folderze. Sprawdź wersje i wykonaj operacje wejścia/wyjścia plików za pomocą poleceń wejścia/wyjścia plików. Udostępnij API aplikacji internetowej lub innej aplikacji klienckiej i pozwól serwerowi określić uprawnienia do plików i mapowanie użytkownika za pomocą plików XML.

Migracja serwerów? Zip i kopiuj. Cross Peron? Zip i kopiuj. Wsparcie? Zip i kopiuj.

To back-end z plikami płaskimi, który uwielbiam na przykład w Mercurial DVC.

Oczywiście, w tym małym przykładzie,pliki rev, może mają daty, godziny, kompresję itp., itd., zdefiniowane w wersjach.plik xml. Gdy chcesz uzyskać dostęp do jednej z tych wersji, ujawniasz metodę AccessFile (), którą Twoja aplikacja serwerowa przyjrzy się tym wersjom.xml, i określić, jak otworzyć ten plik, czy dostęp jest przyznany, itp.

Więc masz

DATA
| + ROOT
| | . metadata.xml
| | |
| | + REVISIONS
| | | . revisionsdata.xml
| | | . documenta.doc.00.rev
| | | . documenta.doc.01.rev
| | | . documentb.ppt.00.rev
| | | . documentb.ppt.03.rev
| | |___
| | |
| | . documenta.doc
| | . documentb.ppt
| | |
| | + GROUP_A
| | | . metadata.xml
| | | |
| | | + REVISIONS
| | | | . revisionsdata.xml
| | | | . documentc.doc.00.rev
| | | | . documentc.doc.01.rev
| | | | . documentd.ppt.00.rev
| | | | . documentd.ppt.03.rev
| | | |___
| | |
| | | . documentc.doc
| | | . documentd.ppt
| | |___
| | |
| | + GROUP_B
| | | . metadata.xml
| | |___
| |
| |___
|
|___
 1
Author: maxwellb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-18 20:07:12

Sprawdź ProjectPier (oryginalnie ActiveCollab ). Ma podobny system i można spojrzeć na ich źródło.

 0
Author: Ryan Schumacher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-09 21:50:08

Uploading plików is to 1990-ty =) Spójrz na Google Wave! Możesz po prostu zbudować całą aplikację wokół ich "kontroli wersji" framework.

 0
Author: Alexander Kosenkov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-13 09:01:09

To nie takie proste, na jakie wygląda. Przeczytaj Ten artykuł autorstwa Erica Sinka na temat konsekwencji przechowywania tych plików.

Być może lepszym pytaniem byłoby to, jakie pliki są ładowane i czy dobrze nadają się do wersjonowania (jak pliki tekstowe)

 0
Author: Rad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-16 09:07:28

Myślę, że to opisuje idealny system do wersjonowania

Http://tom.preston-werner.com/2009/05/19/the-git-parable.html

 0
Author: Ram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-06 09:36:58