xref: /trunk/test/odf-validate/fixtures/base/make.py (revision 0e16a31d78a652c56c5c0fc79c752f48b9048df9)
1*0e16a31dSJim Jagielski#**************************************************************
2*0e16a31dSJim Jagielski#
3*0e16a31dSJim Jagielski#  Licensed to the Apache Software Foundation (ASF) under one
4*0e16a31dSJim Jagielski#  or more contributor license agreements.  See the NOTICE file
5*0e16a31dSJim Jagielski#  distributed with this work for additional information
6*0e16a31dSJim Jagielski#  regarding copyright ownership.  The ASF licenses this file
7*0e16a31dSJim Jagielski#  to you under the Apache License, Version 2.0 (the
8*0e16a31dSJim Jagielski#  "License"); you may not use this file except in compliance
9*0e16a31dSJim Jagielski#  with the License.  You may obtain a copy of the License at
10*0e16a31dSJim Jagielski#
11*0e16a31dSJim Jagielski#    http://www.apache.org/licenses/LICENSE-2.0
12*0e16a31dSJim Jagielski#
13*0e16a31dSJim Jagielski#  Unless required by applicable law or agreed to in writing,
14*0e16a31dSJim Jagielski#  software distributed under the License is distributed on an
15*0e16a31dSJim Jagielski#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*0e16a31dSJim Jagielski#  KIND, either express or implied.  See the License for the
17*0e16a31dSJim Jagielski#  specific language governing permissions and limitations
18*0e16a31dSJim Jagielski#  under the License.
19*0e16a31dSJim Jagielski#
20*0e16a31dSJim Jagielski# usage: runpy.sh fixtures/base/make.py <port> <outdir> [<workdir>]
21*0e16a31dSJim Jagielski# Writes base-<variant>.odb data source documents into <outdir>; dbf, csv and hsqldb files go to <workdir>.
22*0e16a31dSJim Jagielskiimport os, shutil, sys, traceback, uno
23*0e16a31dSJim Jagielskifrom unohelp import connect, pv
24*0e16a31dSJim Jagielskifrom com.sun.star.beans import NamedValue
25*0e16a31dSJim Jagielskifrom com.sun.star.awt import Size, Point
26*0e16a31dSJim Jagielskifrom com.sun.star.lang import Locale
27*0e16a31dSJim Jagielski
28*0e16a31dSJim Jagielskiport, out = int(sys.argv[1]), os.path.abspath(sys.argv[2])
29*0e16a31dSJim Jagielskiwork = os.path.abspath(sys.argv[3]) if len(sys.argv) > 3 else os.path.join(os.path.dirname(out), "work")
30*0e16a31dSJim Jagielskictx = connect(port)
31*0e16a31dSJim Jagielskism = ctx.ServiceManager
32*0e16a31dSJim Jagielskidbc = sm.createInstanceWithContext("com.sun.star.sdb.DatabaseContext", ctx)
33*0e16a31dSJim Jagielskios.makedirs(out, exist_ok=True)
34*0e16a31dSJim Jagielskios.makedirs(work, exist_ok=True)
35*0e16a31dSJim JagielskiFURL = uno.systemPathToFileUrl
36*0e16a31dSJim JagielskiANCHOR = uno.Enum("com.sun.star.text.TextContentAnchorType", "AT_PARAGRAPH")
37*0e16a31dSJim Jagielski
38*0e16a31dSJim Jagielski
39*0e16a31dSJim Jagielskidef nv(n, v):
40*0e16a31dSJim Jagielski    return NamedValue(n, v)
41*0e16a31dSJim Jagielski
42*0e16a31dSJim Jagielski
43*0e16a31dSJim Jagielskidef set_info(ds, **kw):
44*0e16a31dSJim Jagielski    # Info= with several settings crashes the office in comphelper::OPropertyBag; set them one by one
45*0e16a31dSJim Jagielski    bag = ds.Settings
46*0e16a31dSJim Jagielski    for k, v in kw.items():
47*0e16a31dSJim Jagielski        if bag.getPropertySetInfo().hasPropertyByName(k):
48*0e16a31dSJim Jagielski            uno.invoke(bag, "setPropertyValue", (k, v))
49*0e16a31dSJim Jagielski        else:
50*0e16a31dSJim Jagielski            uno.invoke(bag, "addProperty", (k, 128 | 1, v))
51*0e16a31dSJim Jagielski
52*0e16a31dSJim Jagielski
53*0e16a31dSJim Jagielskidef new_source(url, **props):
54*0e16a31dSJim Jagielski    ds = dbc.createInstance()
55*0e16a31dSJim Jagielski    ds.URL = url
56*0e16a31dSJim Jagielski    for k, v in props.items():
57*0e16a31dSJim Jagielski        setattr(ds, k, v)
58*0e16a31dSJim Jagielski    return ds
59*0e16a31dSJim Jagielski
60*0e16a31dSJim Jagielski
61*0e16a31dSJim Jagielskidef sql(conn, stmts):
62*0e16a31dSJim Jagielski    st = conn.createStatement()
63*0e16a31dSJim Jagielski    for s in stmts:
64*0e16a31dSJim Jagielski        st.executeUpdate(s)
65*0e16a31dSJim Jagielski    st.close()
66*0e16a31dSJim Jagielski
67*0e16a31dSJim Jagielski
68*0e16a31dSJim Jagielskidef hsql_connect(ds):
69*0e16a31dSJim Jagielski    # the first statement on a fresh embedded database fails on a null context class loader; a retry works
70*0e16a31dSJim Jagielski    conn = ds.getConnection("", "")
71*0e16a31dSJim Jagielski    st = conn.createStatement()
72*0e16a31dSJim Jagielski    for _ in range(3):
73*0e16a31dSJim Jagielski        try:
74*0e16a31dSJim Jagielski            st.executeUpdate('CREATE MEMORY TABLE "PROBE" ("ID" INTEGER)')
75*0e16a31dSJim Jagielski            st.executeUpdate('DROP TABLE "PROBE"')
76*0e16a31dSJim Jagielski            break
77*0e16a31dSJim Jagielski        except Exception:
78*0e16a31dSJim Jagielski            pass
79*0e16a31dSJim Jagielski    st.close()
80*0e16a31dSJim Jagielski    return conn
81*0e16a31dSJim Jagielski
82*0e16a31dSJim Jagielski
83*0e16a31dSJim Jagielskidef numkey(ds, code):
84*0e16a31dSJim Jagielski    nf = ds.NumberFormatsSupplier.NumberFormats
85*0e16a31dSJim Jagielski    loc = Locale("en", "US", "")
86*0e16a31dSJim Jagielski    k = nf.queryKey(code, loc, False)
87*0e16a31dSJim Jagielski    return k if k != -1 else nf.addNew(code, loc)
88*0e16a31dSJim Jagielski
89*0e16a31dSJim Jagielski
90*0e16a31dSJim Jagielskidef make_query(ds, name, command, **props):
91*0e16a31dSJim Jagielski    q = ds.QueryDefinitions.createInstance()
92*0e16a31dSJim Jagielski    q.Command = command
93*0e16a31dSJim Jagielski    for k, v in props.items():
94*0e16a31dSJim Jagielski        setattr(q, k, v)
95*0e16a31dSJim Jagielski    ds.QueryDefinitions.insertByName(name, q)
96*0e16a31dSJim Jagielski    return ds.QueryDefinitions.getByName(name)
97*0e16a31dSJim Jagielski
98*0e16a31dSJim Jagielski
99*0e16a31dSJim Jagielskidef add_columns(owner, specs):
100*0e16a31dSJim Jagielski    cols = owner.Columns
101*0e16a31dSJim Jagielski    for name, props in specs:
102*0e16a31dSJim Jagielski        d = cols.createDataDescriptor()
103*0e16a31dSJim Jagielski        d.Name = name
104*0e16a31dSJim Jagielski        for k, v in props.items():
105*0e16a31dSJim Jagielski            d.setPropertyValue(k, v)
106*0e16a31dSJim Jagielski        cols.appendByDescriptor(d)
107*0e16a31dSJim Jagielski
108*0e16a31dSJim Jagielski
109*0e16a31dSJim Jagielskidef make_table_def(ds, name, columns=(), **props):
110*0e16a31dSJim Jagielski    tables = ds.Tables
111*0e16a31dSJim Jagielski    if tables.hasByName(name):
112*0e16a31dSJim Jagielski        t = tables.getByName(name)
113*0e16a31dSJim Jagielski        for k, v in props.items():
114*0e16a31dSJim Jagielski            t.setPropertyValue(k, v)
115*0e16a31dSJim Jagielski    else:
116*0e16a31dSJim Jagielski        t = tables.createInstance()
117*0e16a31dSJim Jagielski        for k, v in props.items():
118*0e16a31dSJim Jagielski            t.setPropertyValue(k, v)
119*0e16a31dSJim Jagielski        tables.insertByName(name, t)
120*0e16a31dSJim Jagielski        t = tables.getByName(name)
121*0e16a31dSJim Jagielski    add_columns(t, columns)
122*0e16a31dSJim Jagielski    return t
123*0e16a31dSJim Jagielski
124*0e16a31dSJim Jagielski
125*0e16a31dSJim Jagielskidef new_doc_def(container, name, service, parent=None):
126*0e16a31dSJim Jagielski    args = (nv("Name", name), nv("DocumentServiceName", service))
127*0e16a31dSJim Jagielski    d = container.createInstanceWithArguments("com.sun.star.sdb.DocumentDefinition", args)
128*0e16a31dSJim Jagielski    (parent or container).insertByName(name, d)
129*0e16a31dSJim Jagielski    return d
130*0e16a31dSJim Jagielski
131*0e16a31dSJim Jagielski
132*0e16a31dSJim Jagielskidef open_def(container, name, conn):
133*0e16a31dSJim Jagielski    return container.loadComponentFromURL(name, "", 0, (pv("OpenMode", "openDesign"), pv("ActiveConnection", conn)))
134*0e16a31dSJim Jagielski
135*0e16a31dSJim Jagielski
136*0e16a31dSJim Jagielskidef def_command(container, name, command):
137*0e16a31dSJim Jagielski    cmd = uno.createUnoStruct("com.sun.star.ucb.Command")
138*0e16a31dSJim Jagielski    cmd.Name = command
139*0e16a31dSJim Jagielski    cmd.Handle = -1
140*0e16a31dSJim Jagielski    container.getByName(name).execute(cmd, 0, None)
141*0e16a31dSJim Jagielski
142*0e16a31dSJim Jagielski
143*0e16a31dSJim Jagielskidef store_def(container, name):
144*0e16a31dSJim Jagielski    def_command(container, name, "store")
145*0e16a31dSJim Jagielski    def_command(container, name, "close")
146*0e16a31dSJim Jagielski
147*0e16a31dSJim Jagielski
148*0e16a31dSJim Jagielskidef add_control(doc, form, service, name, x, y, w=4000, h=700, **props):
149*0e16a31dSJim Jagielski    m = doc.createInstance("com.sun.star.form.component." + service)
150*0e16a31dSJim Jagielski    for k, v in props.items():
151*0e16a31dSJim Jagielski        setattr(m, k, v)
152*0e16a31dSJim Jagielski    form.insertByName(name, m)
153*0e16a31dSJim Jagielski    shape = doc.createInstance("com.sun.star.drawing.ControlShape")
154*0e16a31dSJim Jagielski    shape.AnchorType = ANCHOR
155*0e16a31dSJim Jagielski    shape.Size = Size(w, h)
156*0e16a31dSJim Jagielski    shape.Position = Point(x, y)
157*0e16a31dSJim Jagielski    shape.Control = m
158*0e16a31dSJim Jagielski    doc.DrawPage.add(shape)
159*0e16a31dSJim Jagielski    return m
160*0e16a31dSJim Jagielski
161*0e16a31dSJim Jagielski
162*0e16a31dSJim JagielskiCUSTOMER_CONTROLS = (
163*0e16a31dSJim Jagielski    ("FixedText", "Title", dict(Label="Customers")),
164*0e16a31dSJim Jagielski    ("TextField", "NameBox", dict(DataField="NAME", MaxTextLen=40)),
165*0e16a31dSJim Jagielski    ("NumericField", "IdBox", dict(DataField="ID", DecimalAccuracy=0, ValueMin=0.0, ValueMax=9999.0)),
166*0e16a31dSJim Jagielski    ("CheckBox", "ActiveBox", dict(DataField="ACTIVE", Label="Active", TriState=True)),
167*0e16a31dSJim Jagielski    ("DateField", "BornBox", dict(DataField="BORN", DateFormat=4)),
168*0e16a31dSJim Jagielski    ("CurrencyField", "BalBox", dict(DataField="BALANCE", CurrencySymbol="$", PrependCurrencySymbol=True)),
169*0e16a31dSJim Jagielski    ("ListBox", "CityList", dict(DataField="CITY", ListSourceType=2, ListSource=('SELECT DISTINCT "CITY" FROM "CUSTOMERS"',),
170*0e16a31dSJim Jagielski                                 Dropdown=True)),
171*0e16a31dSJim Jagielski    ("ComboBox", "CityCombo", dict(DataField="CITY", ListSourceType=0, StringItemList=("Berlin", "Paris"))),
172*0e16a31dSJim Jagielski    ("CommandButton", "Ok", dict(Label="Save", ButtonType=2)),
173*0e16a31dSJim Jagielski)
174*0e16a31dSJim Jagielski
175*0e16a31dSJim Jagielski
176*0e16a31dSJim Jagielskidef fill_form(doc, command, controls=CUSTOMER_CONTROLS, sub=True):
177*0e16a31dSJim Jagielski    forms = doc.DrawPage.Forms
178*0e16a31dSJim Jagielski    main = doc.createInstance("com.sun.star.form.component.DataForm")
179*0e16a31dSJim Jagielski    main.Command = command
180*0e16a31dSJim Jagielski    main.CommandType = 0
181*0e16a31dSJim Jagielski    main.Filter = '"ID" > 0'
182*0e16a31dSJim Jagielski    main.ApplyFilter = True
183*0e16a31dSJim Jagielski    main.Order = '"NAME"'
184*0e16a31dSJim Jagielski    forms.insertByName("MainForm", main)
185*0e16a31dSJim Jagielski    y = 300
186*0e16a31dSJim Jagielski    for service, name, props in controls:
187*0e16a31dSJim Jagielski        add_control(doc, main, service, name, 500, y, **props)
188*0e16a31dSJim Jagielski        y += 900
189*0e16a31dSJim Jagielski    if sub:
190*0e16a31dSJim Jagielski        child = doc.createInstance("com.sun.star.form.component.DataForm")
191*0e16a31dSJim Jagielski        child.Command = command
192*0e16a31dSJim Jagielski        child.CommandType = 0
193*0e16a31dSJim Jagielski        child.MasterFields = ("ID",)
194*0e16a31dSJim Jagielski        child.DetailFields = ("ID",)
195*0e16a31dSJim Jagielski        main.insertByName("SubForm", child)
196*0e16a31dSJim Jagielski        add_control(doc, child, "GridControl", "Grid", 500, y, w=6000, h=2500)
197*0e16a31dSJim Jagielski        add_control(doc, child, "RadioButton", "R1", 7000, 300, Label="One", RefValue="1", DataField="ID")
198*0e16a31dSJim Jagielski        add_control(doc, child, "RadioButton", "R2", 7000, 1200, Label="Two", RefValue="2", DataField="ID")
199*0e16a31dSJim Jagielski
200*0e16a31dSJim Jagielski
201*0e16a31dSJim Jagielskidef populate(ds, conn, command="CUSTOMERS", folder=True):
202*0e16a31dSJim Jagielski    doc = ds.DatabaseDocument
203*0e16a31dSJim Jagielski    fd = doc.FormDocuments
204*0e16a31dSJim Jagielski    new_doc_def(fd, "Form1", "com.sun.star.text.TextDocument")
205*0e16a31dSJim Jagielski    f = open_def(fd, "Form1", conn)
206*0e16a31dSJim Jagielski    fill_form(f, command)
207*0e16a31dSJim Jagielski    store_def(fd, "Form1")
208*0e16a31dSJim Jagielski    if folder:
209*0e16a31dSJim Jagielski        grp = fd.createInstanceWithArguments("com.sun.star.sdb.Forms", (pv("Name", "Folder"),))
210*0e16a31dSJim Jagielski        fd.insertByName("Folder", grp)
211*0e16a31dSJim Jagielski        new_doc_def(fd, "Form2", "com.sun.star.text.TextDocument", parent=grp)
212*0e16a31dSJim Jagielski        f = open_def(grp, "Form2", conn)
213*0e16a31dSJim Jagielski        fill_form(f, command, controls=CUSTOMER_CONTROLS[:3], sub=False)
214*0e16a31dSJim Jagielski        store_def(grp, "Form2")
215*0e16a31dSJim Jagielski    rd = doc.ReportDocuments
216*0e16a31dSJim Jagielski    new_doc_def(rd, "Report1", "com.sun.star.text.TextDocument")
217*0e16a31dSJim Jagielski    r = open_def(rd, "Report1", conn)
218*0e16a31dSJim Jagielski    fill_form(r, command, controls=CUSTOMER_CONTROLS[:2], sub=False)
219*0e16a31dSJim Jagielski    store_def(rd, "Report1")
220*0e16a31dSJim Jagielski
221*0e16a31dSJim Jagielski
222*0e16a31dSJim Jagielskidef new_hsqldb(name, **props):
223*0e16a31dSJim Jagielski    path = os.path.join(out, name)
224*0e16a31dSJim Jagielski    for p in (path, path + ".lck"):
225*0e16a31dSJim Jagielski        if os.path.exists(p):
226*0e16a31dSJim Jagielski            os.remove(p)
227*0e16a31dSJim Jagielski    ds = new_source("sdbc:embedded:hsqldb", **props)
228*0e16a31dSJim Jagielski    ds.DatabaseDocument.storeAsURL(FURL(path), ())
229*0e16a31dSJim Jagielski    return ds
230*0e16a31dSJim Jagielski
231*0e16a31dSJim Jagielski
232*0e16a31dSJim Jagielskidef new_dir(name):
233*0e16a31dSJim Jagielski    d = os.path.join(work, name)
234*0e16a31dSJim Jagielski    shutil.rmtree(d, ignore_errors=True)
235*0e16a31dSJim Jagielski    os.makedirs(d)
236*0e16a31dSJim Jagielski    return d
237*0e16a31dSJim Jagielski
238*0e16a31dSJim Jagielski
239*0e16a31dSJim Jagielskidef finish(ds, name, conn=None):
240*0e16a31dSJim Jagielski    doc = ds.DatabaseDocument
241*0e16a31dSJim Jagielski    doc.store()
242*0e16a31dSJim Jagielski    if conn is not None:
243*0e16a31dSJim Jagielski        conn.close()
244*0e16a31dSJim Jagielski    doc.close(True)
245*0e16a31dSJim Jagielski    lck = os.path.join(out, name + ".lck")
246*0e16a31dSJim Jagielski    if os.path.exists(lck):
247*0e16a31dSJim Jagielski        os.remove(lck)
248*0e16a31dSJim Jagielski
249*0e16a31dSJim Jagielski
250*0e16a31dSJim Jagielskidef save_new(ds, name):
251*0e16a31dSJim Jagielski    path = os.path.join(out, name)
252*0e16a31dSJim Jagielski    if os.path.exists(path):
253*0e16a31dSJim Jagielski        os.remove(path)
254*0e16a31dSJim Jagielski    ds.DatabaseDocument.storeAsURL(FURL(path), ())
255*0e16a31dSJim Jagielski
256*0e16a31dSJim Jagielski
257*0e16a31dSJim Jagielskidef variant_hsqldb():
258*0e16a31dSJim Jagielski    ds = new_hsqldb("base-hsqldb.odb", TableFilter=("%",), TableTypeFilter=("TABLE", "VIEW"), User="", IsPasswordRequired=False)
259*0e16a31dSJim Jagielski    conn = hsql_connect(ds)
260*0e16a31dSJim Jagielski    sql(conn, ['CREATE MEMORY TABLE "CUSTOMERS" ("ID" INTEGER NOT NULL PRIMARY KEY, "NAME" VARCHAR(50), "CITY" VARCHAR(30), '
261*0e16a31dSJim Jagielski               '"ACTIVE" BOOLEAN, "BORN" DATE, "BALANCE" DECIMAL(10,2))',
262*0e16a31dSJim Jagielski               'CREATE MEMORY TABLE "ORDERS" ("OID" INTEGER NOT NULL PRIMARY KEY, "CID" INTEGER, "TOTAL" DOUBLE, '
263*0e16a31dSJim Jagielski               'FOREIGN KEY ("CID") REFERENCES "CUSTOMERS"("ID"))',
264*0e16a31dSJim Jagielski               'CREATE VIEW "BIGORDERS" AS SELECT * FROM "ORDERS" WHERE "TOTAL" > 100'])
265*0e16a31dSJim Jagielski    set_info(ds, IsAutoRetrievingEnabled=True, AutoRetrievingStatement="CALL IDENTITY()",
266*0e16a31dSJim Jagielski                   AutoIncrementCreation="GENERATED BY DEFAULT AS IDENTITY", BooleanComparisonMode=1,
267*0e16a31dSJim Jagielski                   SuppressVersionColumns=False)
268*0e16a31dSJim Jagielski    make_query(ds, "Q_ByCity", 'SELECT "ID", "NAME", "CITY" FROM "CUSTOMERS"',
269*0e16a31dSJim Jagielski               Filter='"CITY" = \'Berlin\'', ApplyFilter=True, Order='"NAME"',
270*0e16a31dSJim Jagielski               UpdateTableName="CUSTOMERS", UpdateSchemaName="PUBLIC", UpdateCatalogName="")
271*0e16a31dSJim Jagielski    make_query(ds, "Q_Native", 'SELECT * FROM "ORDERS"', EscapeProcessing=False)
272*0e16a31dSJim Jagielski    q = make_query(ds, "Q_Cols", 'SELECT "OID", "TOTAL" FROM "ORDERS"', RowHeight=800, TextColor=0xFF0000, FontName="Arial")
273*0e16a31dSJim Jagielski    add_columns(q, [("OID", dict(Hidden=True, HelpText="order id")),
274*0e16a31dSJim Jagielski                    ("TOTAL", dict(HelpText="the total", ControlDefault="1.5", Width=4000, Align=2,
275*0e16a31dSJim Jagielski                                   FormatKey=numkey(ds, "#,##0.00")))])
276*0e16a31dSJim Jagielski    make_table_def(ds, "CUSTOMERS", [("NAME", dict(Width=5000, HelpText="customer name", Align=1)),
277*0e16a31dSJim Jagielski                                      ("BALANCE", dict(Hidden=True, ControlDefault="0"))],
278*0e16a31dSJim Jagielski                   Filter='"ACTIVE" = TRUE', ApplyFilter=True, Order='"NAME" DESC',
279*0e16a31dSJim Jagielski                   SchemaName="PUBLIC", CatalogName="CAT", RowHeight=700, TextColor=0x0000FF, FontName="Courier")
280*0e16a31dSJim Jagielski    make_table_def(ds, "ORDERS")
281*0e16a31dSJim Jagielski    populate(ds, conn)
282*0e16a31dSJim Jagielski    finish(ds, "base-hsqldb.odb", conn)
283*0e16a31dSJim Jagielski
284*0e16a31dSJim Jagielski
285*0e16a31dSJim Jagielskidef make_dbf(conn):
286*0e16a31dSJim Jagielski    tbls = conn.Tables
287*0e16a31dSJim Jagielski    t = tbls.createDataDescriptor()
288*0e16a31dSJim Jagielski    t.Name = "CUSTOMERS"
289*0e16a31dSJim Jagielski    cols = t.Columns
290*0e16a31dSJim Jagielski    for name, typ, prec, scale in (("ID", 4, 9, 0), ("NAME", 12, 40, 0), ("CITY", 12, 30, 0), ("ACTIVE", -7, 0, 0),
291*0e16a31dSJim Jagielski                                   ("BORN", 91, 0, 0), ("BALANCE", 3, 10, 2), ("NOTES", -1, 0, 0)):
292*0e16a31dSJim Jagielski        c = cols.createDataDescriptor()
293*0e16a31dSJim Jagielski        c.Name, c.Type, c.Precision, c.Scale = name, typ, prec, scale
294*0e16a31dSJim Jagielski        cols.appendByDescriptor(c)
295*0e16a31dSJim Jagielski    tbls.appendByDescriptor(t)
296*0e16a31dSJim Jagielski    ps = conn.prepareStatement('INSERT INTO "CUSTOMERS" VALUES (?,?,?,?,?,?,?)')
297*0e16a31dSJim Jagielski    for i, name, city, active, born, bal, note in ((1, "Ada", "Berlin", True, (31, 1, 1990), 12.5, "first"),
298*0e16a31dSJim Jagielski                                                   (2, "Bob", "Paris", False, (4, 7, 1985), 0.0, "second")):
299*0e16a31dSJim Jagielski        ps.setInt(1, i)
300*0e16a31dSJim Jagielski        ps.setString(2, name)
301*0e16a31dSJim Jagielski        ps.setString(3, city)
302*0e16a31dSJim Jagielski        ps.setBoolean(4, active)
303*0e16a31dSJim Jagielski        ps.setDate(5, uno.createUnoStruct("com.sun.star.util.Date", *born))
304*0e16a31dSJim Jagielski        ps.setDouble(6, bal)
305*0e16a31dSJim Jagielski        ps.setString(7, note)
306*0e16a31dSJim Jagielski        ps.executeUpdate()
307*0e16a31dSJim Jagielski    ps.close()
308*0e16a31dSJim Jagielski
309*0e16a31dSJim Jagielski
310*0e16a31dSJim Jagielskidef variant_dbase():
311*0e16a31dSJim Jagielski    d = new_dir("dbase")
312*0e16a31dSJim Jagielski    ds = new_source("sdbc:dbase:" + FURL(d) + "/", TableFilter=("CUSTOMERS",), TableTypeFilter=("TABLE",))
313*0e16a31dSJim Jagielski    set_info(ds, Extension="dbf", ShowDeleted=True, CharSet="utf-8")
314*0e16a31dSJim Jagielski    save_new(ds, "base-dbase.odb")
315*0e16a31dSJim Jagielski    conn = ds.getConnection("", "")
316*0e16a31dSJim Jagielski    make_dbf(conn)
317*0e16a31dSJim Jagielski    make_query(ds, "Q_Active", 'SELECT * FROM "CUSTOMERS"', Filter='"ACTIVE" = TRUE', ApplyFilter=True, Order='"NAME"',
318*0e16a31dSJim Jagielski               UpdateTableName="CUSTOMERS")
319*0e16a31dSJim Jagielski    make_table_def(ds, "CUSTOMERS", [("NAME", dict(Width=4000))], Order='"NAME"')
320*0e16a31dSJim Jagielski    populate(ds, conn)
321*0e16a31dSJim Jagielski    finish(ds, "base-dbase.odb", conn)
322*0e16a31dSJim Jagielski
323*0e16a31dSJim Jagielski
324*0e16a31dSJim Jagielskidef variant_flat(name, ext, header, field, text, dec, thousand, charset):
325*0e16a31dSJim Jagielski    d = new_dir(name)
326*0e16a31dSJim Jagielski    sep = field
327*0e16a31dSJim Jagielski    rows = [["ID", "NAME", "CITY", "BALANCE"], ["1", "Ada", "Berlin", "1,250.50"], ["2", "Bob", "Paris", "0.00"]]
328*0e16a31dSJim Jagielski    with open(os.path.join(d, "CUSTOMERS." + ext), "w", encoding="utf-8") as fh:
329*0e16a31dSJim Jagielski        for i, r in enumerate(rows):
330*0e16a31dSJim Jagielski            if i == 0 and not header:
331*0e16a31dSJim Jagielski                continue
332*0e16a31dSJim Jagielski            fh.write(sep.join(text + c + text if c in ("Ada", "Bob", "Berlin", "Paris", "NAME", "CITY") else c for c in r) + "\n")
333*0e16a31dSJim Jagielski    ds = new_source("sdbc:flat:" + FURL(d) + "/", TableFilter=("CUSTOMERS",))
334*0e16a31dSJim Jagielski    set_info(ds, Extension=ext, CharSet=charset, FieldDelimiter=field, StringDelimiter=text, DecimalDelimiter=dec,
335*0e16a31dSJim Jagielski                   ThousandDelimiter=thousand, HeaderLine=header)
336*0e16a31dSJim Jagielski    save_new(ds, "base-%s.odb" % name)
337*0e16a31dSJim Jagielski    make_query(ds, "Q_All", 'SELECT * FROM "CUSTOMERS"')
338*0e16a31dSJim Jagielski    finish(ds, "base-%s.odb" % name)
339*0e16a31dSJim Jagielski
340*0e16a31dSJim Jagielski
341*0e16a31dSJim Jagielskidef variant_flat_csv():
342*0e16a31dSJim Jagielski    variant_flat("flat", "csv", True, ",", '"', ".", ",", "UTF-8")
343*0e16a31dSJim Jagielski
344*0e16a31dSJim Jagielski
345*0e16a31dSJim Jagielskidef variant_flat_txt():
346*0e16a31dSJim Jagielski    variant_flat("flat-txt", "txt", False, ";", "'", ",", ".", "ISO-8859-1")
347*0e16a31dSJim Jagielski
348*0e16a31dSJim Jagielski
349*0e16a31dSJim Jagielskidef variant_mysql():
350*0e16a31dSJim Jagielski    ds = new_source("sdbc:mysql:jdbc:db.example.invalid:3306/shop", User="shopuser", IsPasswordRequired=True,
351*0e16a31dSJim Jagielski                    TableFilter=("shop.%", "!shop.tmp%"), TableTypeFilter=("TABLE", "VIEW", "SYSTEM TABLE"))
352*0e16a31dSJim Jagielski    set_info(ds, JavaDriverClass="org.example.jdbc.Driver", LocalSocket="/var/run/mysqld/mysqld.sock",
353*0e16a31dSJim Jagielski                   SuppressVersionColumns=True, IsAutoRetrievingEnabled=True,
354*0e16a31dSJim Jagielski                   AutoRetrievingStatement="SELECT LAST_INSERT_ID()", AutoIncrementCreation="AUTO_INCREMENT")
355*0e16a31dSJim Jagielski    set_info(ds, ServerTimeout=uno.Any("long", 30))
356*0e16a31dSJim Jagielski    save_new(ds, "base-mysql.odb")
357*0e16a31dSJim Jagielski    make_query(ds, "Q_Orders", "SELECT * FROM `orders` ORDER BY `id`", UpdateTableName="orders", UpdateCatalogName="shop")
358*0e16a31dSJim Jagielski    finish(ds, "base-mysql.odb")
359*0e16a31dSJim Jagielski
360*0e16a31dSJim Jagielski
361*0e16a31dSJim Jagielskidef variant_settings():
362*0e16a31dSJim Jagielski    ds = new_source("sdbc:odbc:SettingsDSN")
363*0e16a31dSJim Jagielski    set_info(ds, MyStringSetting="text", MyBoolSetting=uno.Any("boolean", True), MyIntSetting=uno.Any("long", 42),
364*0e16a31dSJim Jagielski                 MyDoubleSetting=2.5, MyListSetting=("a", "b", "c"))
365*0e16a31dSJim Jagielski    save_new(ds, "base-settings.odb")
366*0e16a31dSJim Jagielski    finish(ds, "base-settings.odb")
367*0e16a31dSJim Jagielski
368*0e16a31dSJim Jagielski
369*0e16a31dSJim Jagielskidef variant_oracle():
370*0e16a31dSJim Jagielski    ds = new_source("jdbc:oracle:thin:@db.example.invalid:1521:XE", User="scott", IsPasswordRequired=True)
371*0e16a31dSJim Jagielski    save_new(ds, "base-oracle.odb")
372*0e16a31dSJim Jagielski    finish(ds, "base-oracle.odb")
373*0e16a31dSJim Jagielski
374*0e16a31dSJim Jagielski
375*0e16a31dSJim Jagielskidef variant_odbc():
376*0e16a31dSJim Jagielski    ds = new_source("sdbc:odbc:ShopDSN", User="odbcuser", IsPasswordRequired=False, TableFilter=("%",))
377*0e16a31dSJim Jagielski    set_info(ds, SystemDriverSettings="DSN=ShopDSN;Timeout=5", UseCatalog=True, EnableSQL92Check=True, AppendTableAliasName=True,
378*0e16a31dSJim Jagielski                   IgnoreDriverPrivileges=False, ParameterNameSubstitution=True, NoNameLengthLimit=True,
379*0e16a31dSJim Jagielski                   BooleanComparisonMode=3)
380*0e16a31dSJim Jagielski    save_new(ds, "base-odbc.odb")
381*0e16a31dSJim Jagielski    make_query(ds, "Q_Odbc", "SELECT 1 FROM x")
382*0e16a31dSJim Jagielski    finish(ds, "base-odbc.odb")
383*0e16a31dSJim Jagielski
384*0e16a31dSJim Jagielski
385*0e16a31dSJim Jagielskidef variant_ldap():
386*0e16a31dSJim Jagielski    ds = new_source("sdbc:address:ldap:ldap.example.invalid:389")
387*0e16a31dSJim Jagielski    set_info(ds, BaseDN="dc=example,dc=invalid", MaxRowCount=uno.Any("long", 25))
388*0e16a31dSJim Jagielski    save_new(ds, "base-ldap.odb")
389*0e16a31dSJim Jagielski    finish(ds, "base-ldap.odb")
390*0e16a31dSJim Jagielski
391*0e16a31dSJim Jagielski
392*0e16a31dSJim Jagielskidef variant_adabas():
393*0e16a31dSJim Jagielski    ds = new_source("sdbc:adabas:dbhost.example.invalid:MYDB", User="control", IsPasswordRequired=True)
394*0e16a31dSJim Jagielski    save_new(ds, "base-adabas.odb")
395*0e16a31dSJim Jagielski    finish(ds, "base-adabas.odb")
396*0e16a31dSJim Jagielski
397*0e16a31dSJim Jagielski
398*0e16a31dSJim JagielskiVARIANTS = [("hsqldb", variant_hsqldb), ("dbase", variant_dbase), ("flat", variant_flat_csv), ("flat-txt", variant_flat_txt),
399*0e16a31dSJim Jagielski            ("mysql", variant_mysql), ("settings", variant_settings), ("oracle", variant_oracle), ("odbc", variant_odbc), ("ldap", variant_ldap),
400*0e16a31dSJim Jagielski            ("adabas", variant_adabas)]
401*0e16a31dSJim Jagielski
402*0e16a31dSJim Jagielskifailed = []
403*0e16a31dSJim Jagielskifor name, fn in VARIANTS:
404*0e16a31dSJim Jagielski    if len(sys.argv) > 4 and name not in sys.argv[4:]:
405*0e16a31dSJim Jagielski        continue
406*0e16a31dSJim Jagielski    try:
407*0e16a31dSJim Jagielski        fn()
408*0e16a31dSJim Jagielski        print("OK", name)
409*0e16a31dSJim Jagielski    except Exception:
410*0e16a31dSJim Jagielski        traceback.print_exc()
411*0e16a31dSJim Jagielski        print("FAIL", name)
412*0e16a31dSJim Jagielski        failed.append(name)
413*0e16a31dSJim Jagielskisys.exit(1 if failed else 0)
414