mirror of
https://github.com/documize/community.git
synced 2025-07-22 22:59:43 +02:00
link persistence
This commit is contained in:
parent
4a17acce11
commit
c27de6bcab
11 changed files with 160 additions and 104 deletions
|
@ -115,7 +115,3 @@ export default Ember.Component.extend({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// editor.insertContent(' <b>It\'s my button!</b> ');
|
|
||||||
// Selects the first paragraph found
|
|
||||||
// tinyMCE.activeEditor.selection.select(tinyMCE.activeEditor.dom.select('p')[0]);
|
|
||||||
|
|
|
@ -39,34 +39,41 @@ export default Ember.Service.extend({
|
||||||
href = `/link/${link.linkType}/${link.id}`;
|
href = `/link/${link.linkType}/${link.id}`;
|
||||||
}
|
}
|
||||||
if (link.linkType === "file") {
|
if (link.linkType === "file") {
|
||||||
href = `${endpoint}/public/attachments/${orgId}/${link.attachmentId}`;
|
href = `${endpoint}/public/attachments/${orgId}/${link.targetId}`;
|
||||||
}
|
}
|
||||||
if (link.linkType === "document") {
|
if (link.linkType === "document") {
|
||||||
href = `/link/${link.linkType}/${link.id}`;
|
href = `/link/${link.linkType}/${link.id}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = `<a data-link-id='${link.id}' data-link-type='${link.linkType}' href='${href}'>${link.title}</a>`;
|
result = `<a data-documize='true' data-link-id='${link.id}' data-link-document-id='${link.documentId}' data-link-target-id='${link.targetId}' data-link-type='${link.linkType}' href='${href}'>${link.title}</a>`;
|
||||||
|
|
||||||
console.log(link);
|
|
||||||
console.log(result);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
link handler
|
||||||
|
- implement link redirect handler --
|
||||||
|
- for documents: client-side detect
|
||||||
|
- for sections:
|
||||||
|
- for attachments: direct link
|
||||||
|
-
|
||||||
|
|
||||||
|
onDelete document/section/file:
|
||||||
|
- mark link table row as ORPHAN
|
||||||
|
- doc view: meta data fetch to load orphaned content
|
||||||
|
|
||||||
|
Keyword search results - docs, section, files
|
||||||
|
|
||||||
we should not redirect to a link that is in the same document!
|
we should not redirect to a link that is in the same document!
|
||||||
|
|
||||||
what happens if we delete attachment?
|
what happens if we delete attachment?
|
||||||
|
|
||||||
UpdatePage(): find and persist links from saved content
|
UpdatePage(): find and persist links from saved content
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1. We need to deal with links server-side
|
1. We need to deal with links server-side
|
||||||
2. We need to click on links in the browser and 'navigate' to linked content
|
2. We need to click on links in the browser and 'navigate' to linked content
|
||||||
|
|
||||||
|
editor.insertContent(' <b>It\'s my button!</b> ');
|
||||||
|
Selects the first paragraph found
|
||||||
|
tinyMCE.activeEditor.selection.select(tinyMCE.activeEditor.dom.select('p')[0]);
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
.link-item {
|
.link-item {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 5px 0;
|
padding: 2px 0;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
color: $color-gray;
|
color: $color-gray;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
{{#each candidates.attachments as |a|}}
|
{{#each candidates.attachments as |a|}}
|
||||||
<li class="link-item" {{ action 'setSelection' a }}>
|
<li class="link-item" {{ action 'setSelection' a }}>
|
||||||
{{#ui/ui-checkbox selected=a.selected}}
|
{{#ui/ui-checkbox selected=a.selected}}
|
||||||
<img class="icon" src="/assets/img/attachments/{{document/file-icon a.attachmentExtension}}" />
|
<img class="icon" src="/assets/img/attachments/{{document/file-icon a.context}}" />
|
||||||
{{ a.title }}
|
{{ a.title }}
|
||||||
{{/ui/ui-checkbox}}
|
{{/ui/ui-checkbox}}
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -69,7 +69,7 @@ func GetLinkCandidates(w http.ResponseWriter, r *http.Request) {
|
||||||
c := entity.LinkCandidate{
|
c := entity.LinkCandidate{
|
||||||
RefID: util.UniqueID(),
|
RefID: util.UniqueID(),
|
||||||
DocumentID: documentID,
|
DocumentID: documentID,
|
||||||
PageID: p.RefID,
|
TargetID: p.RefID,
|
||||||
LinkType: "section",
|
LinkType: "section",
|
||||||
Title: p.Title,
|
Title: p.Title,
|
||||||
}
|
}
|
||||||
|
@ -94,12 +94,12 @@ func GetLinkCandidates(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
c := entity.LinkCandidate{
|
c := entity.LinkCandidate{
|
||||||
RefID: util.UniqueID(),
|
RefID: util.UniqueID(),
|
||||||
DocumentID: documentID,
|
DocumentID: documentID,
|
||||||
AttachmentID: f.RefID,
|
TargetID: f.RefID,
|
||||||
LinkType: "file",
|
LinkType: "file",
|
||||||
Title: f.Filename,
|
Title: f.Filename,
|
||||||
AttachmentExtension: f.Extension,
|
Context: f.Extension,
|
||||||
}
|
}
|
||||||
|
|
||||||
fc = append(fc, c)
|
fc = append(fc, c)
|
||||||
|
|
|
@ -346,25 +346,21 @@ type SitemapDocument struct {
|
||||||
// Link defines a reference between a section and another document/section/attachment.
|
// Link defines a reference between a section and another document/section/attachment.
|
||||||
type Link struct {
|
type Link struct {
|
||||||
BaseEntity
|
BaseEntity
|
||||||
OrgID string `json:"orgId"`
|
OrgID string `json:"orgId"`
|
||||||
UserID string `json:"userId"`
|
UserID string `json:"userId"`
|
||||||
LinkType string `json:"linkType"`
|
LinkType string `json:"linkType"`
|
||||||
SourceID string `json:"sourceId"`
|
SourceID string `json:"sourceId"`
|
||||||
DocumentID string `json:"documentId"`
|
DocumentID string `json:"documentId"`
|
||||||
PageID string `json:"pageId"`
|
TargetID string `json:"targetId"`
|
||||||
AttachmentID string `json:"attachmentId"`
|
Orphan bool `json:"orphan"`
|
||||||
Orphan bool `json:"orphan"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkCandidate defines a potential link to a document/section/attachment.
|
// LinkCandidate defines a potential link to a document/section/attachment.
|
||||||
type LinkCandidate struct {
|
type LinkCandidate struct {
|
||||||
RefID string `json:"id"`
|
RefID string `json:"id"`
|
||||||
OrgID string `json:"orgId"`
|
LinkType string `json:"linkType"`
|
||||||
LinkType string `json:"linkType"`
|
DocumentID string `json:"documentId"`
|
||||||
DocumentID string `json:"documentId"`
|
TargetID string `json:"targetId"`
|
||||||
PageID string `json:"pageId"`
|
Title string `json:"title"` // what we label the link
|
||||||
AttachmentID string `json:"attachmentId"`
|
Context string `json:"context"` // additional context (e.g. excerpt, parent, file extension)
|
||||||
AttachmentExtension string `json:"attachmentExtension"`
|
|
||||||
Title string `json:"title"` // what we label the link
|
|
||||||
Context string `json:"context"` // additional context (e.g. excerpt, parent)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,14 +20,14 @@ import (
|
||||||
"github.com/documize/community/core/utility"
|
"github.com/documize/community/core/utility"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AddLink inserts wiki-link into the store.
|
// AddContentLink inserts wiki-link into the store.
|
||||||
// These links exist when content references another document or content.
|
// These links exist when content references another document or content.
|
||||||
func (p *Persister) AddLink(l entity.Link) (err error) {
|
func (p *Persister) AddContentLink(l entity.Link) (err error) {
|
||||||
l.UserID = p.Context.UserID
|
l.UserID = p.Context.UserID
|
||||||
l.Created = time.Now().UTC()
|
l.Created = time.Now().UTC()
|
||||||
l.Revised = time.Now().UTC()
|
l.Revised = time.Now().UTC()
|
||||||
|
|
||||||
stmt, err := p.Context.Transaction.Preparex("INSERT INTO link (refid, orgid, userid, sourceid, documentid, pageid, linktype, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")
|
stmt, err := p.Context.Transaction.Preparex("INSERT INTO link (refid, orgid, userid, sourceid, documentid, targetid, linktype, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")
|
||||||
defer utility.Close(stmt)
|
defer utility.Close(stmt)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -35,7 +35,7 @@ func (p *Persister) AddLink(l entity.Link) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = stmt.Exec(l.RefID, l.OrgID, l.UserID, l.SourceID, l.DocumentID, l.PageID, l.LinkType, l.Created, l.Revised)
|
_, err = stmt.Exec(l.RefID, l.OrgID, l.UserID, l.SourceID, l.DocumentID, l.TargetID, l.LinkType, l.Created, l.Revised)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unable to execute insert for link", err)
|
log.Error("Unable to execute insert for link", err)
|
||||||
|
@ -49,7 +49,7 @@ func (p *Persister) AddLink(l entity.Link) (err error) {
|
||||||
func (p *Persister) GetReferencedLinks(sectionID string) (links []entity.Link, err error) {
|
func (p *Persister) GetReferencedLinks(sectionID string) (links []entity.Link, err error) {
|
||||||
err = nil
|
err = nil
|
||||||
|
|
||||||
sql := "SELECT id,refid,orgid,userid,sourceid,documentid,sectionid,linktype,orphan,created,revised from link WHERE orgid=? AND sourceid=?"
|
sql := "SELECT id,refid,orgid,userid,sourceid,documentid,targetid,linktype,orphan,created,revised from link WHERE orgid=? AND sourceid=?"
|
||||||
|
|
||||||
err = Db.Select(&links, sql, p.Context.OrgID, sectionID)
|
err = Db.Select(&links, sql, p.Context.OrgID, sectionID)
|
||||||
|
|
||||||
|
@ -61,11 +61,11 @@ func (p *Persister) GetReferencedLinks(sectionID string) (links []entity.Link, e
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLinksToSection returns all links that are linking to the specified section.
|
// GetContentLinksForSection returns all links that are linking to the specified section.
|
||||||
func (p *Persister) GetLinksToSection(sectionID string) (links []entity.Link, err error) {
|
func (p *Persister) GetContentLinksForSection(sectionID string) (links []entity.Link, err error) {
|
||||||
err = nil
|
err = nil
|
||||||
|
|
||||||
sql := "SELECT id,refid,orgid,userid,sourceid,documentid,sectionid,linktype,orphan,created,revised from link WHERE orgid=? AND sectionid=?"
|
sql := "SELECT id,refid,orgid,userid,sourceid,documentid,targetid,linktype,orphan,created,revised from link WHERE orgid=? AND sectionid=?"
|
||||||
|
|
||||||
err = Db.Select(&links, sql, p.Context.OrgID, sectionID)
|
err = Db.Select(&links, sql, p.Context.OrgID, sectionID)
|
||||||
|
|
||||||
|
@ -77,11 +77,11 @@ func (p *Persister) GetLinksToSection(sectionID string) (links []entity.Link, er
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLinksToDocument returns all links that are linking to the specified document.
|
// GetContentLinksForDocument returns all links that are linking to the specified document.
|
||||||
func (p *Persister) GetLinksToDocument(documentID string) (links []entity.Link, err error) {
|
func (p *Persister) GetContentLinksForDocument(documentID string) (links []entity.Link, err error) {
|
||||||
err = nil
|
err = nil
|
||||||
|
|
||||||
sql := "SELECT id,refid,orgid,userid,sourceid,documentid,sectionid,linktype,orphan,created,revised from link WHERE orgid=? AND documentid=?"
|
sql := "SELECT id,refid,orgid,userid,sourceid,documentid,targetid,linktype,orphan,created,revised from link WHERE orgid=? AND documentid=?"
|
||||||
|
|
||||||
err = Db.Select(&links, sql, p.Context.OrgID, documentID)
|
err = Db.Select(&links, sql, p.Context.OrgID, documentID)
|
||||||
|
|
||||||
|
@ -93,8 +93,8 @@ func (p *Persister) GetLinksToDocument(documentID string) (links []entity.Link,
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkLinkAsOrphan marks the link record as being invalid.
|
// MarkOrphanContentLink marks the link record as being invalid.
|
||||||
func (p *Persister) MarkLinkAsOrphan(l entity.Link) (err error) {
|
func (p *Persister) MarkOrphanContentLink(l entity.Link) (err error) {
|
||||||
l.Orphan = true
|
l.Orphan = true
|
||||||
l.Revised = time.Now().UTC()
|
l.Revised = time.Now().UTC()
|
||||||
|
|
||||||
|
@ -116,50 +116,12 @@ func (p *Persister) MarkLinkAsOrphan(l entity.Link) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteSourceLinks removes saved links for given source.
|
||||||
|
func (p *Persister) DeleteSourceLinks(sourceID string) (rows int64, err error) {
|
||||||
|
return p.Base.DeleteWhere(p.Context.Transaction, fmt.Sprintf("DELETE FROM link WHERE orgid=\"%s\" AND sourceid=\"%s\"", p.Context.OrgID, sourceID))
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteLink removes saved link from the store.
|
// DeleteLink removes saved link from the store.
|
||||||
func (p *Persister) DeleteLink(id string) (rows int64, err error) {
|
func (p *Persister) DeleteLink(id string) (rows int64, err error) {
|
||||||
return p.Base.DeleteConstrained(p.Context.Transaction, "link", p.Context.OrgID, id)
|
return p.Base.DeleteConstrained(p.Context.Transaction, "link", p.Context.OrgID, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLinkCandidates returns matching results based upon specified parameters.
|
|
||||||
// func (p *Persister) GetLinkCandidates(keywords string) (c []entity.LinkCandidate, err error) {
|
|
||||||
// err = nil
|
|
||||||
//
|
|
||||||
// sql := "SELECT id,refid,orgid,userid,sourceid,documentid,sectionid,linktype,orphan,created,revised from link WHERE orgid=? AND sectionid=?"
|
|
||||||
//
|
|
||||||
// err = Db.Select(&links, sql, p.Context.OrgID, sectionID)
|
|
||||||
//
|
|
||||||
// if err != nil {
|
|
||||||
// log.Error(fmt.Sprintf("Unable to execute select links for org %s", p.Context.OrgID), err)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// package main
|
|
||||||
//
|
|
||||||
// import (
|
|
||||||
// "fmt"
|
|
||||||
// "regexp"
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// var imgRE = regexp.MustCompile(`<a[^>]+\bhref=["']([^"']+)["']`)
|
|
||||||
//
|
|
||||||
// func findImages(htm string) []string {
|
|
||||||
// imgs := imgRE.FindAllStringSubmatch(htm, -1)
|
|
||||||
// out := make([]string, len(imgs))
|
|
||||||
// for i := range out {
|
|
||||||
// out[i] = imgs[i][1]
|
|
||||||
// }
|
|
||||||
// return out
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// func main() {
|
|
||||||
// fmt.Printf("%q", findImages(data))
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const data = `
|
|
||||||
// <p>dfdfdf</p><a href="/link/section/34354"><x><z?>
|
|
||||||
// <a czx zcxz href='/link/file/file.exe'><x><z?>
|
|
||||||
// `
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
|
|
||||||
"github.com/documize/community/core/api/endpoint/models"
|
"github.com/documize/community/core/api/endpoint/models"
|
||||||
"github.com/documize/community/core/api/entity"
|
"github.com/documize/community/core/api/entity"
|
||||||
|
"github.com/documize/community/core/api/util"
|
||||||
"github.com/documize/community/core/log"
|
"github.com/documize/community/core/log"
|
||||||
"github.com/documize/community/core/utility"
|
"github.com/documize/community/core/utility"
|
||||||
)
|
)
|
||||||
|
@ -286,6 +287,27 @@ func (p *Persister) UpdatePage(page entity.Page, refID, userID string, skipRevis
|
||||||
//}
|
//}
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
// fimnd any content links
|
||||||
|
links := util.GetContentLinks(page.Body)
|
||||||
|
|
||||||
|
// delete previous content links for this page
|
||||||
|
_, _ = p.DeleteSourceLinks(page.RefID)
|
||||||
|
|
||||||
|
// save latest content links for this page
|
||||||
|
for _, link := range links {
|
||||||
|
link.OrgID = p.Context.OrgID
|
||||||
|
link.UserID = p.Context.UserID
|
||||||
|
link.SourceID = page.RefID
|
||||||
|
link.Orphan = false
|
||||||
|
|
||||||
|
err := p.AddContentLink(link)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error(fmt.Sprintf("Unable to insert content links for page %s", page.RefID), err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
p.Base.Audit(p.Context, "update-page", page.DocumentID, page.RefID)
|
p.Base.Audit(p.Context, "update-page", page.DocumentID, page.RefID)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
73
core/api/util/links.go
Normal file
73
core/api/util/links.go
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||||
|
//
|
||||||
|
// This software (Documize Community Edition) is licensed under
|
||||||
|
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||||
|
//
|
||||||
|
// You can operate outside the AGPL restrictions by purchasing
|
||||||
|
// Documize Enterprise Edition and obtaining a commercial license
|
||||||
|
// by contacting <sales@documize.com>.
|
||||||
|
//
|
||||||
|
// https://documize.com
|
||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/net/html"
|
||||||
|
|
||||||
|
"github.com/documize/community/core/api/entity"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetContentLinks returns Documize generated <a> links.
|
||||||
|
// such links have an identifying attribute e.g. <a data-documize='true'...
|
||||||
|
func GetContentLinks(body string) (links []entity.Link) {
|
||||||
|
z := html.NewTokenizer(strings.NewReader(body))
|
||||||
|
|
||||||
|
for {
|
||||||
|
tt := z.Next()
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case tt == html.ErrorToken:
|
||||||
|
// End of the document, we're done
|
||||||
|
return
|
||||||
|
case tt == html.StartTagToken:
|
||||||
|
t := z.Token()
|
||||||
|
|
||||||
|
// Check if the token is an <a> tag
|
||||||
|
isAnchor := t.Data == "a"
|
||||||
|
if !isAnchor {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the content link
|
||||||
|
ok, link := getLink(t)
|
||||||
|
if ok {
|
||||||
|
links = append(links, link)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to pull the href attribute from a Token
|
||||||
|
func getLink(t html.Token) (ok bool, link entity.Link) {
|
||||||
|
ok = false
|
||||||
|
|
||||||
|
// Iterate over all of the Token's attributes until we find an "href"
|
||||||
|
for _, a := range t.Attr {
|
||||||
|
switch a.Key {
|
||||||
|
case "data-documize":
|
||||||
|
ok = true
|
||||||
|
case "data-link-id":
|
||||||
|
link.RefID = strings.TrimSpace(a.Val)
|
||||||
|
case "data-link-document-id":
|
||||||
|
link.DocumentID = strings.TrimSpace(a.Val)
|
||||||
|
case "data-link-target-id":
|
||||||
|
link.TargetID = strings.TrimSpace(a.Val)
|
||||||
|
case "data-link-type":
|
||||||
|
link.LinkType = strings.TrimSpace(a.Val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
|
@ -319,14 +319,14 @@ CREATE TABLE IF NOT EXISTS `link` (
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`refid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
`refid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
`sourceid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
|
||||||
`documentid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
|
||||||
`sectionid` CHAR(16) DEFAULT '' COLLATE utf8_bin,
|
|
||||||
`userid` CHAR(16) DEFAULT '' COLLATE utf8_bin,
|
`userid` CHAR(16) DEFAULT '' COLLATE utf8_bin,
|
||||||
|
`sourceid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
`linktype` CHAR(16) NOT NULL COLLATE utf8_bin,
|
`linktype` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
|
`documentid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
|
`targetid` CHAR(16) DEFAULT '' COLLATE utf8_bin,
|
||||||
`orphan` BOOL NOT NULL DEFAULT 0,
|
`orphan` BOOL NOT NULL DEFAULT 0,
|
||||||
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
`revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
`revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
CONSTRAINT pk_id PRIMARY KEY (id))
|
CONSTRAINT pk_id PRIMARY KEY (id))
|
||||||
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
|
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
|
||||||
ENGINE = InnoDB;
|
ENGINE = InnoDB;
|
||||||
|
|
|
@ -5,11 +5,11 @@ CREATE TABLE IF NOT EXISTS `link` (
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`refid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
`refid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
`sourceid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
|
||||||
`documentid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
|
||||||
`sectionid` CHAR(16) DEFAULT '' COLLATE utf8_bin,
|
|
||||||
`userid` CHAR(16) DEFAULT '' COLLATE utf8_bin,
|
`userid` CHAR(16) DEFAULT '' COLLATE utf8_bin,
|
||||||
|
`sourceid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
`linktype` CHAR(16) NOT NULL COLLATE utf8_bin,
|
`linktype` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
|
`documentid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
|
`targetid` CHAR(16) DEFAULT '' COLLATE utf8_bin,
|
||||||
`orphan` BOOL NOT NULL DEFAULT 0,
|
`orphan` BOOL NOT NULL DEFAULT 0,
|
||||||
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
`revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
`revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue